URL slug generator
A slug is what remains of a title once only letters, digits and one separator are allowed. The trap is not the accents: it is the ligatures and the apostrophes that break quick implementations.
Accents are removed by Unicode decomposition (NFD), the œ and æ ligatures are expanded, the German eszett becomes ss, and the Danish ø becomes o.
How the check works
- 1
Accents are decomposed
NFD normalisation splits the letter from its accent, which is then dropped: é becomes e.
- 2
The cases NFD misses are handled
œ becomes oe, æ becomes ae, ß becomes ss, ø becomes o, ł becomes l.
- 3
Everything else becomes the separator
Punctuation and spaces turn into dashes, with no duplicates and none at the edges.
What breaks quick implementations
Simply stripping accents turns 'cœur' into 'cur' — the œ ligature is not an accented letter, so NFD does not decompose it. Same for ß, ø and ł. A typographic apostrophe (’) differs from a straight one (') and has to be handled separately.
A slug should not change
It is part of the URL, therefore part of the indexed address. Changing it amounts to publishing a new page and losing the old one's history, unless you set up a 301. Better to freeze it at publication than regenerate it every time the title is edited.
Frequently asked questions
Hyphen or underscore in a URL?
Hyphen. Google treats the hyphen as a word separator and the underscore as a word character: 'my_article' reads as one term, 'my-article' as two. The recommendation has been constant for fifteen years.
Should accents be kept in a URL?
Technically, URLs accept percent-encoded UTF-8. In practice 'été' becomes '%C3%A9t%C3%A9' the moment the address is copied, which is unreadable in an email or a citation. An accent-free slug is safer.
How long should a slug be?
Long enough to describe, short enough to fit a search result: three to six words is almost always enough. Stop words (the, of, and) can be dropped without losing meaning, but it is not mandatory.
The same check over API
This tool runs in your browser. To run the same check from your code, in bulk or server-side, the API answers in JSON.
Read the documentation