RepoPilot

How does this library handle transliteration of non-ASCII characters?

About sindresorhus/slugify · 2 messages · last activity 7/20/2026

Question

How does this library handle transliteration of non-ASCII characters?

RepoPilot

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:

  1. Builds a combined customReplacements map by merging builtinOverridableReplacements (defaults like &and, 🦄unicorn, love) with any user-supplied customReplacements [index.js:L67-L70].
  2. Passes the string, replacements map, and optional locale to the external transliterate() function (from the @sindresorhus/transliterate dependency [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 the builtinOverridableReplacements map used inside the transliterate() call — confirmed by the test showing foo & bar stays as foo-bar (not foo-and-bar) unless you explicitly add & to customReplacements [test.js:L237-L245].
  • The regex used to strip disallowed characters (buildPatternSlug) also changes: when transliterate is false, it adds \p{L}\p{N} (Unicode letter/number categories) to the allowed character set and uses the u (Unicode) regex flag instead of just g, 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 locale option affect transliteration rules?
  • What are the built-in overridable replacements?
  • How does buildPatternSlug construct its regex pattern?

Want to ask your own question?

Open chat for sindresorhus/slugify

Public Q&A. Generated by RepoPilot from the actual source of sindresorhus/slugify. AI answers can be incomplete or stale — verify before relying on them.