Text Tools· 5 min read

Text to Slug: How Unicode Normalization Turns 'café' into 'cafe'

Understand the NFKD normalization trick behind accent-stripping, and why it matters more than simple lowercase-and-replace logic.

By EasyText Team Last updated: 2026-08-20.

An accented character isn't one character — sometimes it's two

Stripping an accent from a letter sounds like it should be a simple character-replacement problem: swap é for e, ü for u, and so on. But Unicode complicates this in a way that trips up naive implementations — a character like é can be encoded two different ways: as a single precomposed code point, or as the plain letter e followed by a separate combining acute accent mark (a distinct code point that visually attaches to the character before it). A simple find-and-replace list mapping 'é' to 'e' only catches the first encoding; it silently misses the second, leaving a stray combining mark in the output.

This tool sidesteps that entirely by using Unicode NFKD normalization first, which decomposes every precomposed accented character into its base letter plus separate combining marks — guaranteeing a consistent representation regardless of how the original text happened to be encoded. Once every accent is a separate, isolated combining mark, stripping the range U+0300–U+036F (the block reserved for combining diacritical marks) removes them all in one consistent pass, regardless of which specific accent or which original encoding produced them.

See it in action

What NFKD normalization actually changes

StepInput exampleWhat happens
Before normalizationcafé (é as one precomposed character, or e + combining accent)Inconsistent internal representation depending on source
After NFKD normalizationcafe + combining acute accent (separate code points)Base letter and accent mark are always split apart
After stripping U+0300–U+036FcafeCombining mark removed, leaving the plain base letter

Generating a slug

Type or paste your title into the input field — the slug updates live as you type.

Toggle 'Collapse consecutive separators' if you want single hyphens between words rather than multiple in a row.

Review the slug shown in the mono-font box.

Click Copy to grab the slug for your URL or filename.

Why punctuation becomes a separator instead of just disappearing

Anything in your input that isn't a lowercase letter, a digit, or whitespace gets treated as a separator rather than simply deleted outright — this distinction matters. If punctuation were deleted with no trace, 'hello,world' would collapse into 'helloworld', merging two words that were never meant to touch. By treating punctuation as an effective separator first (the same as whitespace), 'hello,world' correctly becomes 'hello-world' instead, preserving the intended word boundary that a naive strip-and-delete approach would destroy.

Why collapsing consecutive separators matters for clean output

Once punctuation and whitespace are both treated as separators, a title with multiple adjacent punctuation marks or spaces — like 'Coffee -- Really Good!' — can produce runs of consecutive hyphens if those runs aren't collapsed down to one. Toggling 'Collapse consecutive separators' on ensures any such run reduces to a single hyphen, which is the standard, expected convention for a clean URL slug; leaving multiple consecutive hyphens in a live URL looks unpolished and can occasionally cause inconsistent behavior in tools or scripts that parse slugs assuming single-hyphen separation.

Why lowercase specifically, not just 'consistent case'

The slug is always output in lowercase, which reflects the actual convention for URL-safe slugs rather than an arbitrary style choice. While URLs are technically case-sensitive per the spec, the overwhelming real-world convention — used by virtually every CMS, blogging platform, and static site generator — is all-lowercase slugs, both for visual consistency and to sidestep any ambiguity or duplicate-URL issues that could arise if the same content were reachable at both differently-cased paths.

Common mistakes

Assuming a simple lowercase-and-hyphenate script handles accented characters correctly — without proper Unicode normalization, some accent encodings slip through unstripped.

Forgetting to enable 'Collapse consecutive separators' on a title with heavy or repeated punctuation, resulting in a slug with multiple hyphens in a row.

Manually stripping accents with a hardcoded character-replacement list, which misses less common letters and alternate encodings that NFKD normalization handles uniformly.

Reusing a slug generated from a title that later changes — since the slug is derived text, it needs regenerating whenever the source title is edited to stay in sync.

Real use cases

Converting a blog post title into a clean, SEO-friendly URL path.

Generating filename-safe versions of titles with accented characters for cross-platform file naming.

Creating consistent anchor-link identifiers from section headings on a long page.

Turning international, accent-heavy titles into ASCII-safe slugs for systems that don't handle Unicode paths well.

Frequently asked questions

Q: How are accents and diacritics handled?

A: The text is NFKD-normalized and combining diacritical marks (U+0300–U+036F) are stripped, so 'café' becomes 'cafe' and 'München' becomes 'munchen'.


Q: What happens to punctuation?

A: Anything that isn't a–z, 0–9, or whitespace is removed, effectively becoming a separator, and then runs of separators collapse to a single hyphen.


Q: Is the slug lowercase?

A: Yes — the slug is always lowercase, which is the standard convention for URL-safe slugs.


Q: Can I use this for filenames?

A: Yes. The output is also filename-safe on every major OS, with no spaces or special characters.


Q: Is anything uploaded?

A: No — slug generation runs entirely in your browser.


Q: Why does 'München' become 'munchen' instead of 'muenchen', which is the more common German transliteration?

A: NFKD normalization strips the combining diacritical mark from ü, leaving the base letter u — it performs accent removal, not linguistic transliteration, so it won't apply language-specific substitution rules like ü → ue that a native German speaker might expect.

Generate your slug now

Try the Text to Slug tool. Need to change letter casing for other purposes? Use the Case Converter. Replacing specific text before slugifying? Try Find & Replace, or check length with the Word Counter.

Need help using this tool?

Read our complete Text to Slug tutorial for step-by-step guidance.

Ready to try the tool?

No accounts. No uploads. No limits. Start now.