Slugify a title: how to turn any string into a clean URL slug
You have a blog title like "Café au lait, revisited" and you need the URL for it. The transform from human title to cafe-au-lait-revisited is called slugifying, and while it looks trivial, the details, accents, punctuation, repeated spaces, are where hand-rolled versions go wrong. Paste any title into the Case Converter & Slugify tool and it produces the slug in your browser, nothing transmitted.
What a slug is and why it matters
A slug is the human readable part of a URL that identifies one page: the slugify-a-title-url-slug in this page's own address. Good slugs matter for three reasons. Readers can tell what a link points to before clicking it. Search engines treat words in the URL as a relevance signal, so a slug built from the title beats an opaque ID. And a slug is a permalink: once published and indexed, it should never change, because every change breaks existing links or costs you a redirect.
The transform, step by step
Every solid slugifier does roughly the same sequence, and order matters:
- Lowercase the whole string. URLs are case sensitive in the path, and mixed case slugs invite duplicate URLs for the same page.
- Trim leading and trailing whitespace.
- Transliterate accented letters to their plain ASCII equivalents:
ébecomese,übecomesu, socafébecomescafe. Do this before stripping, or the accented letters vanish entirely. - Replace spaces and underscores with a hyphen. Runs of whitespace collapse to a single hyphen, not one per space.
- Strip everything that is not a letter, a digit, or a hyphen. Apostrophes, commas, question marks, quotes, and symbols all go.
What'sbecomeswhats, notwhat-s. - Collapse repeated hyphens into one. Stripping punctuation often leaves two hyphens side by side.
- Trim leading and trailing hyphens left over from punctuation at either end.
Examples
| Input | Slug |
|---|---|
10 Tips for Faster Builds | 10-tips-for-faster-builds |
Café au lait, revisited | cafe-au-lait-revisited |
What's New in Node.js 22? | whats-new-in-nodejs-22 |
spaced out__title | spaced-out-title |
"Hello, World!" — a (Brief) History... | hello-world-a-brief-history |
The last row shows why the collapse and trim steps exist: quotes, the dash, parentheses, and the ellipsis all strip away, and without cleanup you would be left with stray and doubled hyphens.
Edge cases worth knowing
Non-latin scripts. Transliteration handles Western European accents well, but a title written entirely in Chinese, Arabic, or Cyrillic may reduce to an empty string under an ASCII only rule. The options are keeping the Unicode characters (modern browsers display them, though they percent-encode on the wire), transliterating with a library that knows the script, or falling back to an ID. Pick one deliberately.
Duplicate slugs. Two posts titled "Weekly update" produce the same slug. Most systems append a numeric suffix, weekly-update-2, on collision. Check uniqueness at publish time, not at render time.
Maximum length. There is no hard limit that matters in practice, but very long slugs get truncated in search results and are painful to share. Around 60 characters, cut at a word boundary, is a sensible cap.
Stability after edits. If you retitle a published post, keep the old slug or add a redirect from it. A slug regenerated on every save silently breaks inbound links, which is the most expensive slugify bug there is.
Slugs are one member of a larger family of naming styles. The same tool also converts text between cases, and if you are deciding between styles for code rather than URLs, camelCase, snake_case, kebab-case, PascalCase: which goes where covers the conventions.