URL slug generator

Turn any headline into a clean, lowercase, hyphen-separated URL slug — the format both search engines and readers prefer.

SEO-Friendly URL Slug Generator

Turn any headline into a clean, lowercase, hyphen-separated URL slug — the format search engines and readers both prefer.

Generated Slug

URL-ready slug
Full URL preview

How to use this tool

The slug is the human-readable tail of a URL, and it does three jobs at once. It tells a person what a page is about before they click, it gives search engines a keyword signal, and it survives being copied into messages and documents without turning into unreadable percent-encoded noise.

Google has recommended simple, descriptive words separated by hyphens for well over a decade. The alternative — /page?id=4821 — tells nobody anything, and when shared it looks like something you shouldn't click.

Hyphens, not underscores

This one has a definitive answer. Google treats a hyphen as a word separator and an underscore as a word joiner. That means css-animations is read as two words, while css_animations is read as the single token "cssanimations" — which nobody searches for.

Also keep slugs lowercase. Web servers on Linux treat URLs as case-sensitive, so /My-Page and /my-page can resolve to different pages — or one of them to a 404 — creating duplicate content or broken links depending on which version gets shared.

Removing stop words — and when not to

Words like "the", "and", "of" and "for" carry little search value, so removing them makes slugs shorter and more keyword-dense. /10-best-css-tricks-beginners-2026-guide reads better than the full headline and loses nothing.

But don't strip blindly. Occasionally a stop word is load-bearing — removing "not" reverses a meaning, and phrases like "The Who" or "Fear of the Dark" break entirely. Read the result before publishing; this tool also keeps the original words if removing them would leave the slug empty.

Never change a published slug

Once a URL is live, it accumulates value: backlinks pointing at it, social shares, bookmarks, and its own ranking history. Change the slug and all of it points to a 404 — you lose the link equity and the visitors at the same time.

If you genuinely must change one, set up a 301 redirect from the old URL to the new one. That passes the accumulated authority across and keeps existing links working. Treat it as a last resort rather than routine tidying, and take a moment to get the slug right before publishing instead.

A few practical limits: keep slugs reasonably short (three to six meaningful words is a good target), strip accents to their ASCII equivalents so the URL doesn't get percent-encoded, and drop dates unless the content is genuinely time-bound — /2024-guide looks stale the moment the year turns.

Slugifying non-English titles: what Unicode normalisation can't fix

Most slugify functions rely on String.prototype.normalize('NFKD'), which is Unicode normalisation: it splits "é" into a plain "e" followed by a combining accent, which you then strip. That handles most Western European accents, and the compatibility (K) form also unpacks ligatures such as "fi". What it can't do is transliterate letters that don't decompose. "ß", "æ", "ø", "ł" and "þ" are letters in their own right, so they survive normalisation and are then deleted by the [^a-z0-9] filter: "Straße" becomes stra-e and "Łódź" loses its first letter.

This generator uses the same normalise-and-strip approach, so check its output for German, Scandinavian, Polish and Icelandic titles. In your own code, map the non-decomposing letters first:

// Letters with no decomposed form: normalize() leaves them untouched,
// so a plain [^a-z0-9] filter would delete them
const TRANSLIT = {
  ß: 'ss', æ: 'ae', œ: 'oe', ø: 'o', ł: 'l', đ: 'd', ð: 'd', þ: 'th', ı: 'i',
};

function slugify(text) {
  return text
    .toLowerCase()
    .replace(/[ßæœøłđðþı]/g, ch => TRANSLIT[ch])
    .normalize('NFKD')            // é → e + U+0301, fi → f + i
    .replace(/\p{M}/gu, '')       // drop the combining marks
    .replace(/['’]/g, '')         // "don't" → "dont", not "don-t"
    .replace(/[^a-z0-9]+/g, '-')
    .replace(/^-+|-+$/g, '');
}

console.log(slugify('Straße & Smørrebrød: Łódź’s café finds'));
// strasse-smorrebrod-lodzs-cafe-finds
// (without the map: stra-e-sm-rrebr-d-odzs-cafe-finds)

Apostrophes are removed before splitting so "don't" becomes dont rather than don-t, and \p{M} with the u flag removes every combining mark rather than only the U+0300–U+036F block most snippets target. For scripts with no Latin form, such as Cyrillic, Greek, Arabic or Chinese, you need a proper transliteration library or a deliberate decision to keep the original characters; Google's URL structure guidelines accept non-ASCII URLs as long as they are percent-encoded in links. MDN's normalize() reference explains the four normalisation forms.

Frequently asked questions

Should URLs use hyphens or underscores?

Hyphens. Google treats a hyphen as a word separator and an underscore as a joiner, so css-animations reads as two words while css_animations reads as one meaningless token. Google has recommended hyphens for over a decade.

Should I remove stop words from URL slugs?

Usually yes — words like the, and and of add length without search value. But check the result, because occasionally a stop word carries meaning, such as "not" or in a title like "The Who".

Can I change a URL slug after publishing?

You can, but you will lose the backlinks, shares and ranking history attached to the old URL unless you add a 301 redirect from old to new. It is far better to get the slug right before publishing.

How long should a URL slug be?

Aim for three to six meaningful words. Long slugs get truncated in search results and are awkward to share, while very short ones may not describe the page well enough to earn a click.