Skip to content
Text 6 min read

URL Slugs: Best Practices for SEO-Friendly URLs

Learn what makes a URL slug SEO-friendly, how to handle Unicode characters, stop words, special characters, and how to generate slugs in JavaScript and Python.

ToolsVito Team

What Is a URL Slug?

A slug is the URL-friendly identifier that appears after the last slash in a page URL:

https://example.com/blog/how-to-generate-url-slugs
                          ↑ this is the slug

A good slug describes the content concisely, contains relevant keywords, uses only lowercase letters, digits, and hyphens, and avoids stop words.

SEO Rules for Slugs

  • Use hyphens, not underscores. Google treats hyphens as word separators; underscores join words into one. url-slug = two words, url_slug = one word "url_slug".
  • Lowercase only. URLs are technically case-sensitive; mixing case creates duplicate content risk.
  • Include the target keyword. The primary keyword in the slug is a light ranking signal.
  • Keep it short. Aim for 3–5 words. Long slugs get truncated in search results and shared links.
  • Remove stop words (a, an, the, and, or, but) unless they are part of the keyword phrase.
  • Never change published slugs without a 301 redirect — broken URLs kill backlink equity and index coverage.

Generating Slugs in JavaScript

function slugify(str) {
  return str
    .toLowerCase()
    .normalize("NFD")               // decompose accented chars: é → e + ́
    .replace(/[\u0300-\u036f]/g, "") // strip diacritics
    .replace(/[^a-z0-9\s-]/g, "")  // remove non-alphanumeric
    .trim()
    .replace(/\s+/g, "-")           // spaces to hyphens
    .replace(/-+/g, "-");           // collapse multiple hyphens
}

slugify("Hello, World! This is a Test.");
// "hello-world-this-is-a-test"

slugify("Héllo Wörld");
// "hello-world"

Generating Slugs in Python

import re
import unicodedata

def slugify(text):
    text = unicodedata.normalize("NFD", text.lower())
    text = "".join(c for c in text if unicodedata.category(c) != "Mn")
    text = re.sub(r"[^a-z0-9\s-]", "", text)
    text = re.sub(r"[\s-]+", "-", text).strip("-")
    return text

# Or use the python-slugify library:
from slugify import slugify
slugify("Hello, World!")  # "hello-world"

Handling Unicode and International Characters

// Transliterate non-ASCII to ASCII equivalents
// Using the 'slugify' npm package
import slugify from "slugify";

slugify("Ärger mit Übergepäck", { locale: "de" });
// "aergermit-ueberpaeaeck"  ← German umlaut expansion

slugify("北京", { locale: "zh" });
// Requires manual transliteration or a library like pinyin

Unique Slugs in a Database

// When title-based slug already exists, append a number
async function uniqueSlug(title, db) {
  const base = slugify(title);
  let slug = base;
  let i = 2;
  while (await db.exists({ slug })) {
    slug = `${base}-${i++}`;
  }
  return slug;
}

Generate Slugs Instantly

Use ToolsVito's Slugify tool to convert any text to a URL-friendly slug with configurable separators and Unicode transliteration.

Try it now — free, runs in your browser

Slugify

URL-friendly slugs