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/20/2026
Here's how transliteration works in this library:
Default behavior (transliterate: true)
Options are merged with defaults where transliterate: true [index.js:L46-L60]. When enabled, the main slugify function:
- Builds a combined
customReplacementsmap by mergingbuiltinOverridableReplacements(defaults like&→and,🦄→unicorn,♥→love) with any user-suppliedcustomReplacements[index.js:L67-L70]. - Passes the string, replacements map, and optional
localeto the externaltransliterate()function (from the@sindresorhus/transliteratedependency [package.json:L36-L38]), which does the actual Unicode-to-ASCII conversion [index.js:L72].
For example, Räksmörgås becomes raeksmoergas by default, using generic transliteration rules, but supplying {locale: 'sv'} uses Swedish-specific rules to instead produce raksmorgas [readme.md:L211-L221].
When transliterate: false
If transliteration is disabled:
- The
transliterate()call is skipped entirely, so non-ASCII characters (accents, CJK, Arabic script, etc.) are preserved as-is rather than being converted [index.js:L74-L78]. - Custom replacements are still manually applied via
string.replaceAll(key, value)in a fallback loop, so users can still substitute specific characters even without full transliteration [index.js:L75-L78]. - However, the built-in replacements (like
&→and) are not applied in this path, since those only come from thebuiltinOverridableReplacementsmap used inside thetransliterate()call — confirmed by the test showingfoo & barstays asfoo-bar(notfoo-and-bar) unless you explicitly add&tocustomReplacements[test.js:L237-L245]. - The regex used to strip disallowed characters (
buildPatternSlug) also changes: whentransliterateisfalse, it adds\p{L}\p{N}(Unicode letter/number categories) to the allowed character set and uses theu(Unicode) regex flag instead of justg, so foreign-script letters aren't stripped out as "invalid" [index.js:L27-L42].
This design lets users trade correctness (full transliteration to ASCII) for performance when they don't need it, while still preserving non-Latin scripts like 你好世界 or مرحبا untouched [test.js:L234-L236].
FOLLOW_UPS:
- How does the
localeoption affect transliteration rules? - What are the built-in overridable replacements?
- How does
buildPatternSlugconstruct its regex pattern?
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.