Turn a title into a URL slug
Converts any title into a lowercase, hyphenated URL slug, stripping accented characters via Unicode normalization along the way.
Last updated
function slugify(text) {
return text
.normalize("NFD")
.replace(/[\u0300-\u036f]/g, "")
.toLowerCase()
.trim()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-+|-+$/g, "");
}
// slugify("Café Déjà Vu!") -> "cafe-deja-vu"How it works
normalize("NFD") decomposes each accented character into a base letter plus a separate combining-accent codepoint (é becomes e + ´), which is what lets the next line strip every accent with one regex: \u0300-\u036f is exactly the Unicode block those combining marks live in. Doing it this way avoids hand-listing every accented letter you might encounter.
The last two replace calls do the actual slugging: any run of characters that isn't a-z or 0-9 collapses to a single dash, then leading/trailing dashes are trimmed — so "100% Done -- Now" becomes "100-done-now" in one pass rather than three separate cleanup steps.
Edge cases to know
- →This only strips Latin diacritics. Non-Latin scripts (Chinese, Arabic, Cyrillic) have no ASCII equivalent to fall back to, so those characters are simply dropped — you'll need transliteration for those, not normalization.
- →Collisions aren't handled: "My Post" and "My Post!" both slugify to "my-post", so uniqueness (append an id or counter) is the caller's job.
- →An all-symbols input (e.g. "???") slugifies to an empty string — worth a fallback (like a generated id) if that's a real input you expect.