URL slug generator

Turns a title into a URL slug, transliterating Hebrew, Arabic, Cyrillic and Greek, with a Unicode path form beside it and collision checks for lists.

Slug
creme-brulee-grusse-aus-munchen
Unicode path — no transliteration, nothing lost
crème-brûlée-grüße-aus-münchen
Percent-encoded — what the server sees
cr%C3%A8me-br%C3%BBl%C3%A9e-gr%C3%BC%C3%9Fe-aus-m%C3%BCnchen

A browser shows the readable form above and sends this one. Both are the same path.

What this tool does

Paste a title in any script and it comes back as the slug a URL can carry: lower case, no punctuation, words joined by a separator you choose. Latin accents are removed, and Hebrew, Arabic, Cyrillic and Greek are transliterated into Latin letters.

Beside the slug sits the same title kept in its own script. That form is a legal path too, and for the scripts that lose the most in transliteration it is often the better answer — so both are produced from one title rather than the tool choosing for you.

What a slug is for

A slug is the human-readable part of a URL: the piece after the last slash that names the page rather than numbering it. It exists because a path that reads as words survives being pasted into a message, printed on a slide, or read aloud over a phone, and a numeric id does none of those.

That is also why the shape is so constrained. A slug should be stable — changing it breaks every link already pointing at the page — and it should be unambiguous when written by hand, which rules out spaces, capitals that a reader may or may not reproduce, and punctuation that means something to a shell or a Markdown parser.

How the accents come off

Most Latin diacritics are removed by the platform rather than by a table. Unicode defines é as decomposable into a plain e followed by a combining acute accent, so normalising to that decomposed form and then discarding every combining mark leaves the plain letter behind. The same operation handles ñ, ç, ő and a few hundred more, and it cannot fall out of date, because it uses the Unicode data the browser already ships.

It does not handle everything, and the gap is worth knowing about. A letter whose mark is a stroke through the glyph rather than a mark above it — ø, ł, đ, ħ, ŧ — is a single indivisible character with no decomposition at all, so removing marks leaves it exactly as it was. So does a ligature: ß, æ and œ each stand for a sequence of sounds, not for a letter plus decoration. All of those need an explicit spelling, and without one they would simply vanish from the slug.

Why the language setting changes the answer

There is no single correct romanisation of ü. German has spelled it ue since before the diaeresis existed — the two dots began as a small superscript e — so Müller is properly mueller, and a German reader will find muller wrong. French, Spanish and Portuguese treat their diacritics as accents on a letter that is otherwise itself, so crème brûlée is properly creme-brulee, and spelling it cruemme would be nonsense.

The Nordic languages disagree with each other in the same way. Danish and Norwegian double the vowel, following the older spelling the letter replaced; Swedish does not:

  • German — ä becomes ae, ö becomes oe, ü becomes ue, ß becomes ss. München is muenchen.
  • Danish and Norwegian — æ becomes ae, ø becomes oe, å becomes aa. Ålborg is aalborg.
  • Swedish — ä becomes a, ö becomes o, å becomes a. Ålborg is alborg.
  • Generic — every mark is dropped and the base letter kept. Ålborg is alborg, München is munchen.

These are not competing approximations of one answer; they are four different correct answers to four different questions. Only one can be the default, so the setting is visible and the tool says which convention produced what you are looking at. One letter is the same everywhere: ß is a ligature rather than an accent, so dropping it would delete a sound, and it is ss in every setting here.

The scripts that need a table

Nothing in the browser romanises Cyrillic, Greek, Hebrew or Arabic, so each is a table written by hand against a published standard. Two of them come out well, because they write their vowels:

  • Cyrillic follows BGN/PCGN, the romanisation on English-language maps and passports: ж is zh, ч is ch, щ is shch, х is kh. Москва becomes moskva and Чехов becomes chekhov.
  • Greek follows ELOT 743, including the digraphs it defines: ου is ou rather than oy, and ευ is ev. Αθήνα becomes athina and Ευρώπη becomes evropi.

ISO 9 is the other well-known Cyrillic standard and is deliberately not used here. It is reversible, which is its point, but it achieves that with diacritics: ж is ž. A slug has no room for a caron, so it would immediately flatten to z — and Жуков and Зуков would become the same slug. The BGN digraph survives the flattening.

One detail in the Cyrillic table is easy to get wrong and worth stating. ё and й look like letters with an accent, and Unicode does decompose them that way, but the mark is what makes them different letters rather than decoration on the same one. Stripping marks before consulting the table — the correct order for every other script here — quietly turns Ёлка into elka and Андрей into andrei.

Hebrew and Arabic, and what they lose

Both scripts write consonants and leave most vowels to points that ordinary text does not carry. That is not an encoding problem this tool could solve with a better table: the information is not in the text. מאמר is four letters, mem-alef-mem-resh, and the reading maamar comes from a reader who already knows the word. Letter by letter it can only be mamr.

What can be done is done. Where a letter doubles as a vowel sign the position is used, because that is the only signal unpointed text leaves:

  • ו and י are consonants at the start of a word and vowel letters inside it, which is what turns שלום into shlom rather than shlvm.
  • A doubled וו or יי is the consonant in both places — that doubling is exactly how Hebrew disambiguates the two readings.
  • ב, כ and פ are a stop at the start of a word and a fricative inside it. The dagesh that marks the difference is a vowel point, so position is all that is left.
  • A letter followed by a geresh is the sound the alphabet has no letter for: ג׳ is j, צ׳ is ch, ז׳ is zh. Ignoring it would turn ג׳אז into a different word.
  • Arabic emphatic consonants collapse onto their plain counterparts, because ASCII has nowhere to put the dot beneath that distinguishes them. صابر and سابر produce the same slug.

The result is readable and recognisable, and it is not a spelling anyone would call correct. The tool says so on every Hebrew or Arabic result rather than presenting a lossy answer as a finished one — and points at the form below, which loses nothing at all.

The Unicode path, which needs no transliteration

A URL path is not limited to ASCII. RFC 3987 defines the IRI — an identifier that may contain any Unicode character — and the rule for putting one on the wire is to encode the UTF-8 bytes as percent escapes. Every browser has done this for two decades, which is why Wikipedia serves its Hebrew and Russian article titles under their own names and the address bar shows them readably.

So the second output here is the title with its punctuation and spacing cleaned up and nothing else touched, and the third is what that actually looks like on the wire. They are the same path: the readable one is what a browser displays and what a person copies, and the encoded one is what the server logs.

Which to use is a real decision rather than a formality. The Unicode form loses nothing, reads correctly to anyone who speaks the language, and is what a search engine will show. The transliterated form survives being pasted into places that mangle encodings, fits in systems that assume ASCII paths, and can be read aloud over a phone. For Hebrew and Arabic in particular the Unicode form is usually the better answer, precisely because the transliteration cannot recover the vowels.

Collisions, and why they are not resolved for you

Slugging strips punctuation, so titles that differ only in punctuation stop differing at all. "Our guide to CSS" and "Our guide to CSS!" are two posts and one slug. In list mode every such clash is marked with the line it collides with, because this is the failure that a content management system hides: it silently appends a suffix, publishes, and the URL you expected belongs to the other post.

The suffix is available as a switch, producing the WordPress and Django style — our-guide-to-css, our-guide-to-css-2 — for the case where a list is meant to be pasted somewhere as it stands. It is off by default because a collision is usually a content problem rather than a naming one, and the collision stays marked even when the switch is on, so turning it on hides nothing.

Length, and cutting in the right place

A length limit cuts on a separator boundary, never inside a word. Truncating mid-word does not produce a shorter slug so much as a different one — introduction-to-crypt is not a tidier introduction-to-cryptography — and half a word is a word that means something else. If a single word is longer than the limit there is no boundary to cut on, and it is returned whole rather than sliced.

There is no universally right limit. Search engines display roughly the first sixty to seventy characters of a URL, and older systems sometimes cap a path segment, but nothing breaks at a particular number. Leaving the field empty leaves the slug as long as the title needs.

Frequently asked questions

What characters are safe in a URL slug?
Lower-case ASCII letters, digits and a single separator will work everywhere without exception. A hyphen is the conventional separator; an underscore works identically but is harder to see under a link that is underlined. Spaces, capitals and punctuation are all technically encodable and all cause trouble in practice, so a slug strips them.
Hyphen or underscore?
A hyphen, for two reasons that outlive fashion. It is what every major platform uses, so it is what readers and other tools expect, and it disappears under the underline that most links carry, which an underscore does not. The choice is offered here because existing systems have existing conventions and consistency inside one site matters more than either answer.
Why does my Hebrew or Arabic title lose its vowels?
Because they were never written down. Both scripts mark most vowels with points that ordinary text omits, so a letter-by-letter reading is all any tool can produce without a vocalisation engine guessing which word was meant. This one transliterates what is actually there, says so on the result, and offers the Unicode path form, which keeps the title exactly as typed.
Can a URL contain Hebrew, Arabic or Chinese directly?
Yes. A path may hold any Unicode character; it is percent-encoded as UTF-8 on the wire and displayed readably by the browser. That is how Wikipedia serves article titles in every language it covers. This tool shows both the readable form and the encoded one, since the second is what appears in server logs and analytics.
Why is Müller sometimes mueller and sometimes muller?
Because both are correct, in different languages. German spells the umlaut out — the two dots began life as a small superscript e — while French and Spanish treat their diacritics as marks on a letter that is otherwise itself. The language setting picks a convention, and the tool tells you which one it applied.
Why do two of my titles produce the same slug?
Because slugging removes punctuation and case, which is often the only thing separating two titles. The list mode marks every collision with the line it clashes with. You can switch on the WordPress-style -2 suffix, but the underlying question — whether two posts should really have almost the same name — is worth answering first.
Does anything I type get sent to a server?
No. Every transformation runs in your browser; nothing is uploaded or logged, and it works with no network connection.