RepoPilot

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

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

Question

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

RepoPilot

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 &and are disabled when transliterate: 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 locale option support besides Swedish and German?
  • How does decamelize interact with transliteration?
  • What custom replacements are applied by default?

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.