Translating Slugs Without Breaking Links

Within Route Mapping for Multilingual Sites, this guide covers localized URL slugs: how to model them, how to normalize characters across languages, how to change them after publication without losing links, and how to migrate a site from shared English slugs to translated ones.

Translated slugs turn /fr/products/hiking-boots into /fr/produits/chaussures-de-randonnee. Readers see URLs in their language, links shared in local communities look native, and the words in the path give a small relevance signal. The cost is that every slug is now content that translators edit, and every edit of a published slug changes a URL. Handled carelessly, translated slugs become a steady source of broken links. Handled with a little tooling, they are safe.

Safeguards for translated slugsFour safeguards keep translated slugs safe: validation of characters and uniqueness in the CMS, normalization of accents and scripts, automatic redirects on change after publication, and a migration path from shared slugs.Validationin the CMS, before publishingcharacters, length, uniqueness per parentNormalizationone canonical formaccents, case, scriptsRedirectsautomatic, flattenedold path → new path on changeMigrationwith redirects for every pathshared slugs → translated
Each layer removes one way translated slugs can break links.

The Problem

A furniture retailer let translators edit slugs freely in all locales. Within a year, analytics showed thousands of 404s from external links in French and Spanish markets. Translators had corrected typos, shortened long slugs and adjusted wording to match new product names, each time changing a published URL without a redirect. Some French slugs also contained uppercase letters and spaces encoded as %20, because the CMS field accepted any text, which produced duplicate URLs that differed only in case.

How to Handle Translated Slugs

Model a slug field per locale. Make the slug a localized field, generated by default from the localized title, and editable. Validate it: lowercase letters, digits and hyphens after normalization, a maximum length, and uniqueness among siblings in the same locale.

Normalize consistently. Decide per locale how to treat accents and non-Latin scripts. Common choices are to strip accents in Latin-script languages (randonnéerandonnee), keep native characters in scripts where transliteration is awkward, and transliterate where local practice prefers ASCII. Apply the same function in the CMS, when slugs are generated, and in the router, when incoming paths are normalized.

Redirect on every change after publication. When a published slug changes, the publish webhook writes a 301 from the old path to the new one, for the page and all its descendants, as described in the route manifest guide. Before first publication, slugs can change freely.

Warn editors. Show a notice on the slug field of published entries: changing it creates a redirect and should be done only for good reasons.

Slug normalization choices by scriptFor Latin-script languages with accents, Cyrillic, Greek, Arabic, Chinese and Japanese, typical slug choices and the trade-offs of each.ScriptCommon choiceTrade-offLatin with accentsstrip accentsASCII, ~ slight loss of meaningCyrillic, Greektransliterate or nativenative reads well, encodes when copiedArabic, Hebrewnative or transliterateRTL in URLs can confuseChinese, Japanesenative, or English slugtransliteration rarely natural
Pick per locale with local advice, then apply the same rule everywhere.

Implementation

A slug normalizer used by both the CMS and the frontend keeps the rules in one place. This version strips accents for Latin-script locales and keeps native characters elsewhere.

TypeScript
// lib/routes/slug.ts
const ASCII_LOCALES = new Set(["en", "de", "fr", "es", "it", "pt", "nl", "pl", "sv"]);

export function normalizeSlug(input: string, locale: string): string {
  let s = input.trim().toLowerCase();
  if (locale === "de") s = s.replace(/ä/g, "ae").replace(/ö/g, "oe").replace(/ü/g, "ue").replace(/ß/g, "ss");
  if (ASCII_LOCALES.has(locale)) {
    s = s.normalize("NFKD").replace(/[̀-ͯ]/g, "");   // strip combining accents
    s = s.replace(/[^a-z0-9]+/g, "-");
  } else {
    s = s.normalize("NFC").replace(/[\s_/?#%&]+/g, "-");      // keep native letters, remove URL-hostile characters
  }
  return s.replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 80);
}

In the CMS, use the same function in a slug field’s generator and validation. Sanity’s slug type accepts a custom slugify function; Contentful apps and Strapi lifecycle hooks can apply it on save. In the frontend, apply it to incoming path segments and redirect to the normalized form when they differ, which turns /fr/Chaussures%20Randonnée into a single redirect to the canonical path instead of a 404 or a duplicate page.

The webhook handler compares the old and new slug on publish and writes redirects.

TypeScript
// app/api/slug-webhook/route.ts (excerpt)
const { id, locale, previousSlug, slug, published } = event;
if (published && previousSlug && previousSlug !== slug) {
  const changes = await recomputeSubtreePaths(id, locale);          // old and new paths for page + descendants
  await applyPathChanges(changes);                                   // updates manifest and writes 301s
  await notifyEditor(id, locale, `${changes.length} redirects created for the slug change`);
}

Migrating from shared slugs

Sites that started with English slugs everywhere can move to translated slugs in one controlled step. Generate translated slugs from localized titles for every published entry, let each market review the list for its locale, especially top-level section slugs, then publish them in one migration together with a redirect for every old path. Keep the old paths in the redirect table for at least a year. Expect a short dip in organic traffic while search engines process the redirects, usually two to four weeks.

Hreflang and translated slugs

Translated slugs mean that the same page has a different path in every locale, so hreflang alternates cannot be built by swapping the locale prefix. They must come from the route manifest, which knows each entry’s path per locale. The same applies to the language switcher and to canonical tags. A common bug after introducing translated slugs is an hreflang builder that still assumes shared slugs and emits alternates like /fr/products/hiking-boots that do not exist, producing hreflang errors in search console for every page. Move all such code onto the manifest before switching slugs, and test with a page whose slug differs in every locale.

Configuration Reference

Setting Recommendation Why
Slug field localized, generated from title Readable URLs without extra work.
Normalization one function, per-locale rules CMS and router agree.
Validation charset, length, uniqueness per parent and locale No duplicates or hostile characters.
Changes after publish allowed, with automatic 301s Corrections without broken links.
Incoming paths normalize and redirect Case and encoding variants resolve.
Redirect retention at least a year External links keep working.

Gotchas & Edge Cases

  • Slugs that differ only by accents. resume and résumé normalize to the same slug; uniqueness must be checked after normalization.
  • Top-level section slugs. Changing a section slug changes every path below it. Review them carefully before launch and change them rarely.
  • Encoded native characters. Native-script slugs appear percent-encoded when copied into some tools. That is valid, but check analytics and log processing handle decoding.
  • Redirect chains. A slug changed twice must redirect the first path straight to the latest one. Flatten chains whenever a redirect is added.

Worked Example

The furniture retailer added normalization and validation to the slug fields, redirects on every published slug change, and path normalization with redirects in the router. It then imported 404 logs from the previous year, matched old paths to current entries by entry id where possible and by similarity otherwise, and created redirects for the 2,100 most requested broken paths. 404s from external links in French and Spanish dropped by over 90 percent in the following month, and translators kept the freedom to fix slugs.

Monthly 404s from external links, French and Spanish sites404 responses from external referrers per month before the change, and in the first and third months after adding slug redirects and recovering historical broken paths.Before8400 404s per monthMonth 1 after690 404s per monthMonth 3 after240 404s per month
Recovered historical paths did most of the work; automatic redirects prevented new ones.

Choosing Slug Words

Translated slugs are small pieces of copy and deserve a little editorial attention. Short slugs of two to five words are easier to read and share than full translated titles. Leave out articles and filler words where the language allows it naturally. Use the terms people search for in that market, which may differ from a literal translation of the English slug; a local SEO or market specialist can review top-level and high-traffic slugs. Avoid dates and version numbers in slugs for evergreen content, since they force slug changes when the content is updated. And keep the product or topic name stable across locales where it is a proper name, which helps readers who switch languages recognize the page.

Rollout Checklist

  • Make slugs localized fields generated from localized titles.
  • Normalize and validate slugs with one shared function per locale.
  • Redirect every published slug change automatically, including descendants.
  • Normalize incoming paths and redirect to the canonical form.
  • Review section slugs with each market before launch.
  • Recover historical 404s from logs with redirects.

Frequently Asked Questions

Are translated slugs worth the effort?

For sites with meaningful organic traffic in several markets, usually yes. For small sites or content mainly reached through navigation, shared slugs are an acceptable, simpler choice.

Should slugs change when titles change?

Not automatically after publication. Titles can change freely; slugs should change only when the old one is misleading or wrong, and each change then goes through the redirect path.

Can two locales share a slug?

Yes, for example for product names. Uniqueness is only required within a locale and its parent, never across different locales.

Who should approve slug changes?

For ordinary pages, the editor, with the automatic redirect as a safety net. For section slugs and high-traffic pages, require a review by the market’s SEO or content lead, since those changes affect many URLs or valuable ones.

How long should redirects be kept?

At least a year, and indefinitely for paths that still receive external traffic. Review redirect traffic yearly and retire only redirects that no longer receive any requests.