CodeToolProCodeToolPro
GitHub
Text·8 min read

Slugify Guide: Convert Titles into URL-Friendly Slugs

CodeToolPro Team·

Slugify Guide: Convert Titles into URL-Friendly Slugs

A slug is the part of a URL that identifies a page in human-readable words — the slugify-guide segment in this very address is a slug. Whenever you publish a blog post, a product, or a documentation page, you need a clean, lowercase, hyphen-separated string instead of the raw title. Our Slugify tool does exactly that in your browser, with no upload and no server round-trip.

This guide explains what a slug is, why it matters for routing and SEO, how the slugify pipeline actually transforms text, and the real, reproducible output we got by running the tool's own algorithm.

What Is a Slug, and Why Slugify?

A URL slug is the tail of a path that names a resource. Compare these two addresses:

  • https://example.com/blog/How To Rank #1 In 2026!!!
  • https://example.com/blog/how-to-rank-1-in-2026

The first one is broken in practice: spaces become %20, the # starts a fragment, and the ! is ambiguous. The second is a proper slug — lowercase, only letters, digits, and hyphens. Slugs matter for three reasons:

  • Routing stability. Most frameworks match paths case-sensitively and reject raw spaces. A normalized slug is safe to use as a route key.
  • Readability & sharing. A slug tells a human what the page is about before they click, and it survives being pasted into chat, email, or print.
  • SEO. Keywords in the URL path are a minor but real ranking signal, and a clean slug is more likely to be kept intact when others link to you.

A slug is not the same as percent-encoding. Slugification removes the offending characters and replaces spaces with hyphens; encoding keeps every character but escapes it. When you only need the URL to parse, reach for the URL Encoder — or read our URL Encoder guide for the difference.

How the Slugify Tool Works

The tool applies a fixed pipeline, in order, to whatever you type:

  1. Unicode normalization (NFKD). Accented characters are decomposed so the diacritic becomes a separate combining mark. é becomes e + ◌́. This lets the next step strip the accent cleanly.
  2. Lowercase. Every letter is folded to lower case for consistent routing.
  3. Trim. Leading and trailing whitespace are removed.
  4. Whitespace → hyphen. Runs of spaces, tabs, and newlines collapse into a single -.
  5. Strip non-word characters. Anything that is not a letter, digit, or hyphen is deleted. This removes punctuation, symbols, and the combining accents left by step 1.
  6. Collapse hyphen runs. Any remaining -- sequences shrink to a single -.
  7. Trim hyphens. Stray - at the very start or end are removed.

One subtle but real detail: the "word character" class (\w) includes the underscore. So an underscore in the input survives, while a space next to it becomes a hyphen. Keep that in mind if your source text mixes the two.

Code Examples

JavaScript

The following function is the exact logic the tool runs, so you can drop it into a build script or server:

function slugify(text) {
  return text
    .toString()
    .normalize("NFKD")          // decompose accents
    .toLowerCase()
    .trim()
    .replace(/\s+/g, "-")       // whitespace -> single hyphen
    .replace(/[^\w-]+/g, "")    // drop non-word, non-hyphen chars
    .replace(/--+/g, "-")       // collapse repeated hyphens
    .replace(/^-+|-+$/g, "");   // trim leading/trailing hyphens
}

console.log(slugify("Hello World!"));        // "hello-world"
console.log(slugify("Café Crème Brûlée"));   // "cafe-creme-brulee"

Python

import re, unicodedata

def slugify(text: str) -> str:
    text = unicodedata.normalize("NFKD", text)   # decompose accents
    text = text.encode("ascii", "ignore").decode("ascii")  # drop marks
    text = text.lower().strip()
    text = re.sub(r"\s+", "-", text)             # whitespace -> hyphen
    text = re.sub(r"[^\w-]+", "", text)          # strip non-word chars
    text = re.sub(r"-{2,}", "-", text)           # collapse hyphens
    return text.strip("-")                       # trim hyphens

print(slugify("2024 Product Launch & Review"))   # 2024-product-launch-review
print(slugify("Don't Stop Me"))                  # dont-stop-me

Both versions normalize, strip, hyphenate, and trim with the same rules, so the output matches the browser tool.

Hands-on: Tested with the Tool

We ran the tool's own slugify function on Node 22 (the managed runtime used by this site) with a set of representative inputs. Every value below is the actual returned string, not an illustration:

InputOutput
Hello World!hello-world
My First Post!!! my-first-post
Café Crème Brûléecafe-creme-brulee
2024 Product Launch & Review2024-product-launch-review
Don't Stop Medont-stop-me
Questions? Comments! @#$questions-comments
_underscore_ test_underscore_-test
`` (empty string)
Top 10 Tips for SEO in 2026top-10-tips-for-seo-in-2026
A/B Testing: Why It Worksab-testing-why-it-works

Observations from the run:

  • Accents are stripped, not mangled. Café Crème Brûlée becomes cafe-creme-brulee because NFKD separates the accent and step 5 deletes the combining mark. If you need to preserve diacritics, this tool is the wrong choice — but for English and most Latin-script SEO slugs, stripping is exactly what you want.
  • Symbols disappear. &, ?, !, @, #, $, /, :, and the apostrophe are all deleted. Punctuation never reaches the slug.
  • Spaces become a single hyphen, and any hyphen that ends up at the edges is trimmed — note how Questions? Comments! @#$ collapses to questions-comments with no trailing dash.
  • Underscores survive. In _underscore_ test, the underscores are kept while the space turns into a hyphen, yielding _underscore_-test.
  • Empty input yields an empty slug. Pure whitespace trims to nothing, so guard against that before saving a route.

Round-tripping is not the goal — a slug is a one-way, lossy summary — but every input above produced a deterministic, repeatable result.

Common Mistakes

  • Shipping the raw title. Spaces and symbols in a path cause %20, broken links, and case-sensitivity bugs. Always slugify before using text as a route.
  • Assuming slugs are unique. Slugification removes information, so two different titles can collide (for example Don't Stop and Dont Stop). A slug is not a primary key — enforce uniqueness in your database.
  • Forgetting accent loss. If a brand or name relies on diacritics, this pipeline drops them. Pick a slugifier that preserves marks, or keep the original name alongside the slug.
  • Mixing underscores and hyphens blindly. Because underscores are retained but spaces become hyphens, _a _b becomes _a-_b. Decide on one separator convention for your site and normalize first.
  • Double hyphens from punctuation. Consecutive symbols can leave -- behind; this tool collapses them, but hand-rolled code that skips that step will not.
  • Treating the slug as secret or stable forever. Slugs are public and often user-facing; changing one later breaks bookmarks and SEO equity unless you add a redirect.

Related Tools

When to Use This Tool Instead of Code

If you are writing application code, slugify is usually a one-liner you keep in your project — the JavaScript and Python snippets above are copy-paste ready. The browser tool earns its place in the moments around coding: drafting a post title in a notes app, renaming a batch of files, sanity-checking what a headline becomes before you commit it to a route, or showing a non-developer teammate the result without spinning up a project. It also gives you a neutral, tested reference implementation to compare your own function against. For production, keep the code; for ad-hoc and collaborative slug work, the tool is faster.