Slugify Text
Generate URL-safe slugs from any text. Handles accents, Unicode, stop words, custom separators, length limits. Free, in-browser.
What this does
Generates URL-safe slugs from any input text — what you’d put in https://example.com/blog/<slug> or as an HTML id.
The pipeline:
- Unicode-normalize (NFKD) and strip combining diacritics so
é→e,ñ→n,ü→u. - Map special characters that NFKD misses —
ß→ss,Ø→O,Æ→AE,Þ→TH,Œ→OE,Ł→L. - Lowercase (toggleable).
- Strip English stop words (toggleable, off by default — useful for shorter SEO slugs).
- Replace any non-alphanumeric character with the separator (default
-). - Collapse runs of separators to a single separator.
- Trim leading/trailing separators.
- Truncate to your max length, breaking on a separator.
Result: a string that’s safe to drop into a URL, an HTML id, a filename, an S3 key, a Kubernetes resource name, a database slug column.
Examples
| Input | Output |
|---|---|
Hello World | hello-world |
10 Best Coffee Shops in São Paulo! | 10-best-coffee-shops-in-sao-paulo |
What's New in TypeScript 5.7? | whats-new-in-typescript-5-7 |
Café — résumé naïve | cafe-resume-naive |
<script>alert(1)</script> | script-alert-1-script |
Why “URL-safe” matters
URLs are technically allowed to contain a lot of characters (RFC 3986 reserves :/?#[]@!$&'()*+,;=). In practice:
- Anything outside
[A-Za-z0-9-._~]should be percent-encoded. A URL with rawébecomescaf%C3%A9in transit. Most browsers display it cleanly, but copy-paste flow, email clients, log aggregators, and some legacy systems mangle it. - Spaces become
%20or+depending on the encoder. Both look ugly in shareable URLs. - Slashes split the path and break routing. Even URL-encoded
%2Fis sometimes blocked or normalized away by web servers.
The safe set is a-z, 0-9, and one separator. Hyphen is conventional for URL slugs (Google states they prefer hyphens to underscores for readability). Underscore is conventional for filenames. Pick based on context.
Common use cases
- Blog post titles → URLs. “Why I Stopped Using AWS” →
/why-i-stopped-using-aws/. Stable, shareable, SEO-friendly. - User input → file names. A user uploads “My Résumé Final (v3).pdf”; you store it as
my-resume-final-v3.pdf. Avoids encoding bugs across S3, Linux, Windows. - Heading anchors. Markdown’s
# Section Title→#section-titleanchor. Same algorithm. - Kubernetes / Docker resource names. These have stricter rules (DNS-1123 subdomain: lowercase, max 63 chars, must not start/end with
-). The defaults here match. - Search engine optimization. A keyword-rich slug ranks better than a numeric ID.
/blog/12345/is worse than/blog/why-i-stopped-using-aws/.
Stop word stripping — when to use
Off by default, because removing words can change meaning. With it on:
The Best of 2026→best-2026(shorter, more keyword-dense)A Tale of Two Cities→tale-two-cities(loses some context)How to Win at AWS→win-aws(loses the “how-to” intent — bad for SEO)
Use stop-word stripping when slug length is the constraint. Skip it when the slug should match natural-language search intent.
What this does NOT do
- Does not transliterate non-Latin scripts.
北京stays北京(and gets replaced with separator, producing an empty slug). Use a transliteration library (unidecode,iconv) for CJK, Cyrillic, Arabic, Hindi. - Does not preserve uniqueness. If you slugify two different titles to the same slug, you get a collision. Add a numeric suffix or a short hash in your application code.
- Does not check against existing slugs. That’s an application-layer concern — query your database before saving.
Privacy
Runs entirely in your browser.