Local browser utility · Examples and limits included

Slug Generator

Turn any title into a URL slug: accents reduced to base letters, symbols spelled out, and characters with no Latin form listed rather than silently dropped.

Enter a title, headline or any text. It becomes a clean URL slug as you type.

0 characters

Options

Separator

Generated slug

Your slug will appear here

Generate several at once

One title per line. Repeats get a numeric suffix, the way a CMS resolves a collision. The options above apply to every line.

Slugs will appear here

Good to knowAccented letters are reduced to their base form, so café becomes cafe. Characters with no Latin equivalent — Chinese, Cyrillic, emoji — are dropped and listed, because a silently empty slug is the failure worth catching.

What the result contains

What This Tool Provides

Turn a title into a URL slug. Accented letters are reduced to their base form so café becomes cafe, symbols that carry meaning are spelled out so 100% becomes 100-percent, and characters with no Latin equivalent are listed rather than silently discarded — because a slug that quietly comes back empty is the failure that actually costs you.

  • A lowercase, hyphen-separated slug from any title
  • Accents reduced through Unicode normalization, not a lookup table
  • A report of any character dropped for having no Latin form
  • Batch mode that resolves repeated titles with numeric suffixes

How to Use This Tool

  1. Paste a titleA headline, a product name, a page title — anything destined for a URL.
  2. Set the shapeHyphen or underscore, lowercase or preserved case, an optional length cap, and optional removal of short words.
  3. Copy, or do a batchCopy the single slug, or paste a list of titles to slug them all with collisions resolved.

How It Works

Most of the work is done by Unicode normalization rather than a translation table. NFD decomposition splits an accented character into a base letter plus a separate combining mark, so removing the combining-mark range leaves the plain letter behind — that single step handles é, ñ, ü, å and every other accented Latin character at once. What normalization cannot do is handle letters that are not decorated versions of anything: German ß, Nordic ø and æ, Polish ł and Turkish ı decompose to themselves, so those go through an explicit map applied first, since several expand to two characters. Everything remaining is lowercased, non-alphanumeric runs become the separator, and repeated separators are collapsed.

Worked Examples

A title with accents and punctuation

Input
Café Owner’s Guide: Naïve Pricing?
Output
cafe-owner-s-guide-naive-pricing

Accents are reduced by normalization, punctuation becomes a separator, and the trailing question mark disappears without leaving a dangling hyphen.

Symbols spelled out rather than dropped

Input
Fish & Chips — 100% Cod
Output
fish-and-chips-100-percent-cod

An ampersand and a percent sign carry meaning, so they become words. Deleting them would give fish-chips-100-cod, which reads worse.

A script that cannot be transliterated

Input
Hello 世界
Output
hello · dropped 世 界 — no Latin equivalent

There is no correct romanization without knowing the language and system, so the characters are dropped and named rather than guessed at.

What Makes a Good Slug

A slug is read by three audiences and they want slightly different things. Search engines use it as a weak relevance signal, so the main keyword belongs in it. People read it in a link before deciding whether to click, so it should be legible and roughly describe the page. And systems parse it, so it should avoid characters that need percent-encoding, which is why the safe set is lowercase letters, digits and a single separator.

Hyphens rather than underscores, for one specific reason: search engines have long treated a hyphen as a word separator and an underscore as a word joiner, so first_post can be read as a single token where first-post is two words. Underscores remain a perfectly reasonable choice for internal identifiers where no search engine is involved.

Length is a matter of judgment rather than a rule. Very long slugs get truncated in search results and are awkward to share, while very short ones lose the keyword that justified having a slug at all. Somewhere around 50 to 60 characters covers most titles without cutting anything meaningful — and when this tool truncates, it breaks at a separator rather than mid-word, because a slug ending in a half-word looks like a bug.

Accents, Normalization, and the Limits of Transliteration

Unicode normalization is the part of this that feels like a trick. A character such as é can be stored as one code point or as an e followed by a combining acute accent, and NFD normalization converts to the second form. Once decomposed, deleting the combining-mark range leaves an ordinary e — so a single normalization step and one deletion handles every accented Latin character there is, with no per-language table to maintain.

The letters that need an explicit map are the ones that are not accented at all. German ß is its own letter and conventionally romanizes to ss. Nordic ø and æ, Polish ł, Icelandic þ and ð, Turkish dotless ı: each is a distinct letter whose decomposition is itself. These are handled before normalization, because several expand into two characters and doing it afterwards would be too late.

Then there is the honest limit. Chinese, Japanese, Arabic, Hebrew, Korean, Cyrillic and Greek have no Latin decomposition, and romanizing them properly requires knowing both the language and which system you want — Pinyin or Wade-Giles, Hepburn or Kunrei, and so on for every script. Choosing one silently would be worse than not trying. So those characters are dropped and reported, and if the result is empty the tool says so instead of handing back an empty string that becomes a broken URL.

Collisions, and Why Slugs Should Not Change

Two different titles regularly produce the same slug — two posts called "Update", or two products differing only in a symbol the slug dropped. The convention every CMS settles on is a numeric suffix starting at 2, because the unsuffixed slug is conceptually the first one. The batch mode here does exactly that, so pasting a list of titles shows you the collisions before they reach your database rather than after.

The more consequential rule is that a slug should stop changing once a URL is published. Regenerating slugs from titles on every save is a tempting feature and a quietly destructive one: every edit to a headline breaks inbound links, discards whatever ranking the old URL accumulated, and invalidates anything anyone bookmarked. Generate the slug once at creation, store it, and let the two drift apart.

When a slug genuinely must change — a wrong product name, a rebrand — the old URL needs a permanent redirect to the new one rather than being left to return a 404. That preserves the links and the ranking. A slug that simply disappears takes both with it.

Where Slugs Fit in the Rest of the Work

Slugs usually appear during a migration or a bulk import, which is why the batch box exists. Content coming out of an old system arrives as a table of titles far more often than as anything structured: converting that CSV to JSON gives you records to slug and load, and the reverse trip back to CSV is how the mapping usually gets handed to whoever is configuring the redirects.

When the content itself is being migrated rather than just the titles, converting the pages to Markdown and slugging their headings tends to be the same afternoon’s work — the slug becomes the filename, so the two steps are really one. Headings arriving from several authors are also rarely consistent, and normalizing their capitalization before slugging avoids a set of files that differ only in case.

A slug is also the wrong tool for one job it gets used for. It is derived from the title, so it is guessable by design — which is fine for a public page and wrong for a private share link, where the whole point is that nobody can find it by trying. Those need a random token, not a slug. Where a bulk slug mapping has to be handed to whoever configures the redirects, it usually travels as JSON, and validating that file before sending it saves a round trip.

Two smaller notes. If a slug is going into a query string rather than a path, or the source title contained characters you chose to keep, percent-encoding it is the step that stops a link breaking. And when you are designing a URL structure before real content exists, placeholder titles give you something realistic to slug and see how the paths look at length. And when a record id travels in the URL beside the slug, it is frequently packed as Base64 rather than printed, which is worth decoding before assuming a path is malformed.

Important Edge Cases

  • A title made entirely of non-Latin characters produces an empty slug. The tool says so explicitly rather than returning an empty string that would become a broken URL.
  • Removing stop words is skipped when it would empty the slug, because a long slug beats no slug.
  • Truncation breaks at a separator, unless the very first word is already longer than the limit, in which case it hard-cuts.
  • An apostrophe becomes a separator rather than being deleted, so "owner’s" becomes owner-s rather than owners.
  • Uppercase and lowercase forms of a special letter both map to the same output, so Straße and STRASSE agree.

Limitations

  • No transliteration is attempted for non-Latin scripts, because doing it correctly needs a language-specific romanization system.
  • Stop-word removal uses a short English list; it is not aware of other languages or of which words matter for your topic.
  • The tool does not know which slugs already exist in your database. Batch mode only resolves collisions within the list you paste.
  • There is no reserved-word checking, so a slug could collide with an existing route such as admin or api.
  • Input is capped at 100,000 characters, which is far beyond any realistic title.

Input handling

Private Browser Processing

Titles are converted entirely in your browser. Nothing is uploaded, stored, or logged, and no request is made while you type — which the network tab will confirm.

Google Analytics records page visits and whether a tool finished or failed, but these tool implementations do not send field values, generated passwords, QR payloads, uploaded QR images, or camera frames to analytics or a Tiny Tiny Tools processing endpoint.

See the Privacy Policy for site-wide details.

Questions About This Tool

Should I use hyphens or underscores?

Hyphens for anything public. Search engines have long treated a hyphen as a word separator and an underscore as a word joiner, so first_post can be read as one token where first-post is two words. Underscores are fine for internal identifiers.

Why were my Chinese characters removed?

Because there is no correct romanization without knowing the language and which system you want. Rather than guess, the tool drops them and lists exactly which characters went, so an empty or shortened slug is visible instead of surprising.

How long should a slug be?

Around 50 to 60 characters suits most titles: long enough to keep the keyword, short enough to survive truncation in search results. When the cap is on here, truncation breaks at a word boundary rather than mid-word.

Should I regenerate slugs when a title changes?

No. Once a URL is published, changing its slug breaks inbound links and discards the ranking the old URL earned. Generate at creation, store it, and let title and slug drift apart. If it truly must change, redirect the old URL permanently.

How does batch mode handle duplicates?

With a numeric suffix starting at 2, which is the convention every CMS uses — the unsuffixed slug is the first one. It only sees the list you paste, so it cannot know what already exists in your database.