What a Slug Is
The slug is the human-readable part of a URL that identifies a page:
``
https://example.com/blog/how-to-build-a-rest-api
└──────── slug ────────┘
`
It is one of the few URL components you control completely, and unlike a title tag it is
effectively permanent — changing it costs you redirects and link equity.
Rules This Generator Follows
| Rule | Why |
|---|---|
| Lowercase everything | URLs are case-sensitive on most servers; /About and /about are two pages |
| Hyphens between words | Google documents hyphens as word separators; underscores join words |
| Transliterate accents | café → cafe, not caf |
| Strip punctuation | ? and & start query strings and break the path |
| Collapse repeats | hello---world → hello-world |
| Trim to a word boundary | Truncating mid-word produces introduction-to-typescr |
Length and Search Results
Google truncates displayed URLs in results at roughly 60–70 characters including the
domain. A slug longer than that is not penalised, but the part a searcher reads gets cut
off. Aim for the shortest slug that still describes the page.
| Title | Slug | Length |
|---|---|---|
| How to Build a REST API in Node.js | how-to-build-a-rest-api-in-nodejs | 33 |
| Same, stop words removed | build-rest-api-nodejs | 21 |
Common Mistakes
Dates in slugs:/2024/01/my-postages the content visibly and forces a redirect
when you update it.
IDs only:/post/48211tells neither a person nor a crawler what the page is.Keyword stuffing:/cheap-best-buy-shoes-online-store-shoesreads as spam.- Changing slugs casually: every change needs a 301, and chained redirects compound.
In Code
`javascript
const slugify = (input) =>
input
.normalize('NFD') // split accents into base + mark
.replace(/[\u0300-\u036f]/g, '') // drop the marks
.toLowerCase()
.replace(/[^a-z0-9]+/g, '-') // non-alphanumerics become separators
.replace(/^-+|-+$/g, ''); // trim leading/trailing hyphens
`
That covers the common case. This tool additionally handles ß, æ, ø, ł and Cyrillic, which
have no combining-mark decomposition and would otherwise vanish.
A Slug Is a URL's Only Readable Part
/blog/how-to-write-a-regex tells a reader and a crawler what the page is before either
loads it. /blog/post?id=4821 tells them nothing. That readability is the whole value, and
it is why generating one properly matters more than it appears.
What Generating a Slug Actually Involves
Lower-casing and replacing spaces is the easy quarter of the job:
1. Transliterate. Crème brûlée must become creme-brulee, not crm-brle. Stripping
non-ASCII destroys the word; mapping it preserves it. The same applies to Cyrillic, Greek
and any script with a conventional romanisation.
2. Lower-case. URLs are case-sensitive in their path, so /About and /about are two
URLs — and a server that treats them as one still lets both be indexed.
3. Replace separators. Punctuation, symbols and whitespace all become the separator.
4. Collapse runs. hello---world is a defect, not a slug.
5. Trim the ends. A leading or trailing separator is always wrong.
6. Truncate at a word boundary. Cutting at 60 characters mid-word produces
how-to-write-a-reg.
Skipping any one of these produces slugs that mostly work, which is worse than slugs that
obviously do not.
Hyphens for URLs, Underscores for Identifiers
Google has stated for years that it treats a hyphen as a word separator and an underscore as
a word joiner. blue_widgets can be read as one token; blue-widgets is read as two
words. For a URL, that settles it.
Underscores win everywhere else, for concrete reasons:
| Context | Separator | Why |
|---|---|---|
| URL path | Hyphen | Word separation in search |
| Filename | Underscore | A leading hyphen looks like a command flag to a shell |
| SQL identifier | Underscore | Hyphens require quoting |
| Python module | Underscore | PEP 8 |
| Environment variable | Underscore | The only separator POSIX allows |
Use the [SEO slug generator](/dev/seo-slug-generator) for URLs and the
[underscore generator](/dev/slug-generator/underscore-slug-generator) for filenames,
database columns and code identifiers.Stop Words Are a Judgement Call
Removing the, a, of and and shortens a slug without changing what it says, and
shorter slugs are marginally better for sharing and display. But how-to-be-a-better-writer
reads properly and how-better-writer does not, so removal is off by default and offered as
a choice.
Keyword stuffing is the failure mode at the other end. best-cheap-affordable-budget-laptops-2026
signals manipulation rather than relevance, and it reads badly in a search result — which is
where the actual decision to click gets made.
Changing a Slug Costs You the URL
A published slug is an address other people have linked to. Changing it without a redirect
throws away every link and every ranking signal the old URL accumulated, and the new one
starts from zero.
If you must change it, 301 the old URL to the new one and leave the redirect in place
permanently. And decide the slug before publishing rather than after: the cheapest redirect
is the one you never needed.
Uniqueness Is Your Database's Problem
Two posts titled "2026 Roadmap" generate the same slug. Adding a numeric suffix
(2026-roadmap-2`) is the usual answer and is fine; deriving the slug from an ID defeats the
point of having one. Enforce a unique index on the column so the collision surfaces at write
time rather than as two pages fighting over one URL.