Turn any text into a URL-friendly slug you can copy and use for blog posts, pages, and product URLs.
hello-world-this-is-my-blog-post-about-cafe-co
-) — Google's recommended word separator — or underscore (_) if your platform requires it. Lowercase is on by default (URLs are case-sensitive, so mixed-case slugs create duplicate-content traps); flip it off only if you need a case-preserving identifier.café → cafe, Naïve → naive, Schöne Grüße → schoene-gruesse, 北京 → bei-jing). Toggle stopword removal to drop filler words like the, a, and, of, in, to. Set a max length (50–60 characters is the common SEO target).A slug is the human-readable tail of a URL — /blog/url-slug-best-practices rather than /blog/?p=4821. Good slugs improve crawlability, click-through rate from search results, social shareability, and accessibility (screen readers announce path segments). Generating them by hand is error-prone: it's easy to leave a stray apostrophe, a capital letter, or a Unicode character that ends up percent-encoded as %E2%80%99 in the final URL.
app/blog/[slug]) read slugs from frontmatter. A typo in the slug breaks <Link> resolution at build time.#installation-on-macos is a slug too. Heading-anchor plugins (rehype-slug, markdown-it-anchor) use the same algorithm; generating them up front keeps your in-page links stable when titles get tweaked./api/categories/home-office). Predictable slugs simplify routing, caching, and analytics.Need a related text utility? Use Text Case Converter to switch between camelCase, snake_case, and kebab-case; URL Encoder for percent-encoding query strings; or Word Counter to check title length against the 50–60 character SEO sweet spot.
Google's URL Structure documentation (developers.google.com/search/docs) is explicit: "we recommend using hyphens (-) instead of underscores (_) to separate words in your URLs, as it helps users and search engines better identify concepts in the URL." John Mueller has restated this many times, with one important caveat: don't redirect existing underscore URLs just to swap them. URL punctuation isn't a ranking signal by itself — it's a parsing aid. The difference matters for new content but isn't worth breaking old links.
| Aspect | Hyphen - |
Underscore _ |
|---|---|---|
| Google parses as | Word separator | Word joiner |
node_js_best_practices reads as |
n/a | nodejsbestpractices (one token) |
node-js-best-practices reads as |
node js best practices |
n/a |
| Programming-identifier compatibility | Invalid in most variable names | Valid in Python/Ruby/C/Java |
| Convention in URLs | Industry default | Mostly legacy / filesystem |
| Mueller's advice for existing URLs | Keep them | Keep them — don't redirect just to switch |
If you're slugifying for a programming context (Python module names, Ruby symbols, environment variables), use _. For anything that ends up in a browser address bar, use -.
| Rule | Recommended | Notes |
|---|---|---|
| Casing | Lowercase only | URLs are case-sensitive per RFC 3986; /About and /about are different resources. Standardise to lowercase so they collapse. |
| Separator | - (hyphen) |
Google's explicit recommendation; the de-facto industry default. |
| Length | ~50–60 characters total path | No hard limit from Google; keep URLs under ~2,000 characters for browser/server compatibility (Chrome and Edge cap reliably around 2 KB; RFC 7230 asks servers to handle ≥8,000 octets). |
| Stopwords | Remove only when context survives | "above" or "below" can change meaning — keep them. "the" and "of" usually drop without loss. |
| Non-ASCII characters | Transliterate to ASCII | Google says non-ASCII "should be percent encoded," which is ugly (%E2%80%99). Transliteration (ö → o or oe) is friendlier. |
| Numbers | OK | top-10-react-frameworks-2026 is fine; just avoid years if the post will be evergreen. |
| Trailing slash | Pick one and stick with it | /post and /post/ are technically different URLs. Configure your server to 301 one to the other. |
| Stability | Set once, never change | Each slug change forfeits accumulated PageRank, backlinks, and crawl history unless you 301-redirect. |
| Source | ASCII output | Notes |
|---|---|---|
café, naïve, Zürich |
cafe, naive, zurich |
Latin-1 supplement — accents stripped |
Schöne Grüße, Mädchen |
schoene-gruesse, maedchen |
German convention expands ö → oe, ü → ue, ä → ae, ß → ss |
garçon, crème brûlée |
garcon, creme-brulee |
French cedillas and circumflexes flattened |
Москва, Жуков |
moskva, zhukov |
Cyrillic via BGN/PCGN or ISO 9 |
Αθήνα |
athina |
Greek transliteration |
北京, 東京 |
bei-jing, tou-kyou |
Chinese (Hanyu Pinyin) and Japanese (Hepburn romaji) |
한국 |
hanguk |
Korean (Revised Romanisation) |
Different libraries pick different conventions — slugify (npm), python-slugify, Django's slugify, and Rails's parameterize all transliterate, but German ö becomes o in some and oe in others. Pick one and document it.
Hyphens. Google's official URL Structure guide explicitly recommends hyphens, and Search Advocates including John Mueller have confirmed this repeatedly. Google treats - as a word separator and _ as a word joiner, so node_js_tutorial is parsed as the single token nodejstutorial while node-js-tutorial is parsed as node js tutorial. That said, Mueller has also said the impact is small and you should not redirect old underscore URLs just to switch — the cost of breaking links outweighs the parsing benefit.
There's no Google-imposed limit. Practical caps are set by browsers and servers: keep total URL length under ~2,000 characters to stay safely within Chrome, Edge, and Safari's reliable rendering range. Apache's default request-line limit is 8,190 bytes; IIS defaults to 4,096; RFC 7230 asks servers to support at least 8,000 octets. For the slug specifically, 50–60 characters is the common SEO target — enough for 3–5 meaningful words, short enough to display in full inside SERP snippets and social previews.
It depends on whether the stopword carries meaning. /growing-up-with-hearing-loss and /growing-hearing-loss mean different things — the first is a memoir, the second sounds like a medical condition. Drop stopwords only when the slug still reads naturally without them: /the-best-react-frameworks can safely become /best-react-frameworks. Yoast and Rank Math include a stopword strip toggle precisely because the answer is "sometimes". Don't strip blindly.
Two options. Percent-encode the original (Google's documented advice) — 北京 becomes %E4%BA%AC%E5%9F%8E, which is technically correct but renders as garbage in tweets, emails, and analytics dashboards. Or transliterate to ASCII — 北京 becomes bei-jing (Pinyin), Москва becomes moskva (BGN/PCGN). Transliteration is friendlier for international users typing or remembering the URL, and standards like Hanyu Pinyin and Hepburn romaji are widely understood. The slug generator transliterates by default; toggle it off if your target audience reads the source script natively and your CMS supports IRIs.
Yes — numbers are valid and often improve click-through rates (top-7-css-frameworks beats top-css-frameworks for some queries). The catch is evergreen content: if you slug a post /best-laptops-2024 and update it annually, you either change the slug (forfeiting backlinks unless you 301-redirect) or end up with a 2024 URL pointing at 2026 content. For perennial articles, drop the year; for genuinely time-bound coverage ("2024 election results"), keep it.
The standard pattern is append-an-incrementing-suffix: WordPress's wp_unique_post_slug() will turn the second /hello-world into /hello-world-2, the third into /hello-world-3, and so on. That's safe but ugly; the better fix is editorial — change one of the titles so the slugs diverge naturally, or scope the slug under a category (/recipes/chocolate-cake vs /reviews/chocolate-cake). Some platforms let you override uniqueness across content types (a page and a post can share a slug) but most CMSes enforce global uniqueness within the site.
Yes, unless you set up a 301 permanent redirect from the old slug to the new one. The old URL has accumulated backlinks, internal links, social shares, and Google's crawl history — all of that signal is bound to the URL string, not the post ID. A 301 forwards both users and link equity (Google now passes effectively 100% of PageRank through 301s, per repeated Mueller confirmations). Without the redirect, the old URL 404s, the equity dies, and Google takes weeks to recrawl and reassociate. Best practice: pick a slug you can live with for years, and only change it when there's a real reason (typo, trademark issue, content pivot).
/About equal /about?Per RFC 3986, the scheme and host parts of a URL are case-insensitive (HTTPS://Example.COM is fine) but the path is case-sensitive — /About and /about are technically two different resources. Most web servers (Apache, Nginx, IIS in default config on Windows) treat the path case-insensitively for filesystem lookups, but Linux-hosted apps, S3 buckets, and many frameworks (Next.js, Express) do not. Google specifically recommends normalising to lowercase so the same content doesn't appear at two URLs. The generator forces lowercase by default for this reason.
A keyword in the slug is a minor positive signal — it confirms relevance and shows up bolded in SERP snippets when it matches the query, which helps click-through. But it's a tiebreaker, not a primary ranking factor. Don't keyword-stuff (buy-cheap-shoes-online-best-shoes-store-shoes) — that signals spam. One or two primary keywords plus a clear topic phrase is the sweet spot.