How does this library handle transliteration of non-ASCII characters?
How does this library handle transliteration of non-ASCII characters?
About sindresorhus/slugify · 2 messages · last activity 7/27/2026
Transliteration is handled through a combination of the transliterate option and the @sindresorhus/transliterate dependency.
Default behavior (transliterate: true)
By default, slugify transliterates Unicode characters to their closest ASCII equivalents before slugifying. This is powered by the @sindresorhus/transliterate package, which is listed as a dependency in [package.json:L50-L52]. This is why examples like slugify('Déjà Vu!') produce 'deja-vu' and slugify('я люблю единорогов') produces 'ya-lyublyu-edinorogov' (per the README).
The transliterate option
You can disable this behavior with {transliterate: false}, documented in [index.d.ts:L161-L192]. When disabled, non-ASCII characters are preserved as-is instead of being converted to ASCII:
slugify('Déjà Vu', {transliterate: false});
//=> 'déjà-vu'
The docs note this can improve performance when transliteration isn't needed [index.d.ts:L172-L176].
This is confirmed in the test suite [test.js:L232-L243], which shows that with transliterate: false:
- ASCII strings behave normally (
'foo bar'→'foo-bar') - Non-ASCII characters are preserved untouched, including accented Latin (
'Déjà Vu'→'déjà-vu'), Swedish ('Räksmörgås'→'räksmörgås'), Chinese ('你好世界'stays'你好世界'), and Arabic ('مرحبا'stays'مرحبا') - Custom replacements still apply even when transliteration is off
- However, built-in replacements like
&→andare disabled whentransliterate: false
How this affects the regex pattern
The internal buildPatternSlug function in [index.js:L23-L43] adjusts its character-matching regex based on the transliterate option. When transliteration is disabled, it adds \p{L}\p{N} (Unicode letter/number properties) to the "allowed characters" pattern so non-ASCII letters and numbers aren't stripped out [index.js:L28-L30]. It also switches the regex flags from 'g' to 'gu' (Unicode mode) when transliteration is off [index.js:L41], which is required for the \p{...} Unicode property escapes to work correctly.
Locale-aware transliteration
There's also a locale option [index.d.ts:L192-L198, readme.md:L208-L221] that fine-tunes transliteration for language-specific rules — e.g., slugify('Räksmörgås') defaults to 'raeksmoergas', but with {locale: 'sv'} (Swedish) it becomes 'raksmorgas', since Swedish handles å/ä/ö differently than German. This is tested in [test.js:L219-L226], and the actual locale logic lives in the separate @sindresorhus/transliterate package that this library depends on.
FOLLOW_UPS:
- What does the
localeoption support besides Swedish and German? - How does
decamelizeinteract with transliteration? - What custom replacements are applied by default?
Want to ask your own question?
Open chat for sindresorhus/slugifyPublic Q&A. Generated by RepoPilot from the actual source of sindresorhus/slugify. AI answers can be incomplete or stale — verify before relying on them.