Slug rules for URLs and filenames
Published: 2026-09-05
How to turn titles into stable URL path segments and safe filenames—separators, Unicode vs ASCII folding, collisions, and how slugify differs from percent-encoding.
A slug is a short, stable string derived from a human title for use in a URL path or filename. Spaces and punctuation become separators; letters are usually lowercased. Good slugs stay readable in the address bar, survive copy-paste, and avoid characters that break paths or shells.
Slugify is a string transform, not a CMS rulebook: frameworks and CDNs still decide redirects, uniqueness, and whether /Blog/ and /blog/ collide. Understanding the transform helps you pick options that match your stack.
What makes a good slug
| Goal | Prefer | Avoid |
|---|---|---|
| Readable URLs | Lowercase words joined by hyphens | Mixed case, %20 from raw spaces |
| Stable links | Deterministic output from the same title | Random suffixes unless you need uniqueness |
| Path safety | Letters, digits, - or _ |
/, ?, #, &, quotes, control characters |
| Cross-system filenames | ASCII-only when tools choke on Unicode | Relying on every OS/encoding to agree |
Example: title Résumé — Café & Øresund 2026! might become:
- Latin ASCII + hyphen:
resume-cafe-oresund-2026 - Unicode + hyphen:
résumé-café-øresund-2026(letters kept; punctuation dropped)
Neither is “more correct”—they solve different constraints (conservative ASCII hosts vs. native-script URLs).
Separators: hyphen vs underscore
- Hyphen (
-) — Default for public URLs and kebab-case. Search engines and humans treat hyphens as word breaks. Path segments like/learn/slug-rules-for-urls-and-filenamesfollow this pattern. - Underscore (
_) — Common in code identifiers and some file naming schemes. Underscores are fine in URLs but are often not treated as word separators for readability.
Use one separator consistently per surface (blog paths vs. download filenames). Mixing both in one slug (user_profile-id) is usually a smell.
Unicode mode vs Latin ASCII folding
Many sites need ASCII path segments so proxies, older analytics, and hand-typed links stay simple. Others want native letters in the path for language-specific brands.
Typical pipeline for a Latin ASCII slug:
- Expand a few compatibility letters (e.g.
ß→ss,œ→oe). - Normalize and strip combining accents (
é→e). - Keep only
a–zand digits; everything else becomes a separator boundary. - Join runs with
-or_and lowercase.
A Unicode mode keeps letters and numbers across scripts after lowercasing, and still drops punctuation and spaces into separators. Prefer that when the title is not Latin-script and you do not want lossy folding. A deterministic slugify is not a curated dictionary for every language—edge scripts may need editorial overrides.
URLs vs filenames
Slugs in URLs sit in a path segment. After you have a clean slug, any remaining reserved characters still need percent-encoding if you assemble the string by hand—but a well-formed slug usually needs little or no further escaping.
Filenames add OS and tool constraints:
- Length limits and reserved names (
CON,NULon Windows). - Leading/trailing dots and spaces.
- Whether the filesystem is case-sensitive (
Photo.jpgvsphoto.jpg).
Treat the slug as the basename; keep the extension separate (report.pdf, not inside the slugified title).
Collisions and uniqueness
Different titles can collapse to the same slug ("Hello!" and "hello" → hello). CMS platforms often append -2, a date, or an id. Do that after slugify, as a product rule—not inside a generic string tool—so previews stay predictable.
When batching many titles, enable one slug per line so each row is independent. Empty lines should stay empty so you can align with a spreadsheet column.
Slugify vs case conversion vs encoding
| Task | Tool / concept |
|---|---|
| Title → path segment / basename | Slugify |
Identifier style (camelCase ↔ snake_case) |
Text case converter |
| Escape reserved URL bytes | URL encoder |
Case conversion preserves more of the original token structure; slugify throws away punctuation and often folds accents. Encoding escapes bytes for transport—it does not invent readable hyphens.
Try it locally
Unpublished post titles and internal doc names do not need to leave your machine. LocalTools’ Slugify runs entirely in the browser:
- Paste a title (or one title per line).
- Choose Unicode or Latin ASCII, and hyphen or underscore.
- Pick whole-box vs per-line batching, then copy the result.
Nothing is uploaded for processing.
Related reading
- Slugify — local URL/filename slugs with Unicode or Latin ASCII options
- Text case styles: camelCase, snake_case, kebab-case
- URL encoding vs form encoding
- Text stats: words, reading time, and limits
- Why “local only” matters for developer tools