Slug Generation for Multilingual URLs: Best Practices

May 28, 20267 min read

Why Multilingual Slugs Are Hard

English URL slugs are straightforward: lowercase, replace spaces with hyphens, strip special characters. But multilingual content introduces characters that don't fit ASCII — accented letters (é, ü, ñ), non-Latin scripts (中文, عربي, キリル), and ligatures (æ, ß).

Now RFC 3986 restricts URLs to a limited ASCII subset. Internationalized Resource Identifiers (IRIs) extend this, but in practice browsers and servers rely on Punycode encoding for non-ASCII domain names and percent-encoding for path segments. Your slug generation strategy must respect these constraints while remaining readable and SEO-friendly.

Three Strategies for Multilingual Slugs

Strategy 1: Transliterate to ASCII

Convert non-ASCII characters to their closest ASCII equivalent:

OriginalTransliteratedSlug
Café au laitCafe au laitcafe-au-lait
MünchenMunchenmunchen
Szczęść BożeSzczesc Bozeszczesc-boze

Pros: Fully ASCII-safe, no encoding issues, works everywhere Cons: Loss of meaning for non-Latin scripts ("北京" → "bei jing" loses the visual connection), inconsistent transliteration libraries

Keep the original characters in the slug. The browser percent-encodes them automatically:

LanguageTitleSlug
Chinese北京旅游指南北京旅游指南
Arabicدليل السفردليل-السفر
Japanese東京観光ガイド東京観光ガイド

Pros: Preserves meaning, better click-through rates for native readers Cons: URLs look encoded when copied (%E5%8C%97%E4%BA%AC), some analytics tools don't handle percent-encoded URLs well

Strategy 3: Hybrid Approach

Use ASCII slugs for Latin-script languages and Unicode slugs for non-Latin:

function generateSlug(text, locale) {
  const normalized = text.toLowerCase().trim()

  if (isLatinScript(locale)) {
    return transliterate(normalized)
      .replace(/[^a-z0-9]+/g, '-')
      .replace(/^-|-$/g, '')
  }

  return normalized
    .replace(/\s+/g, '-')
    .replace(/[^\p{L}\p{N}-]/gu, '')
}

This gives Latin-script users clean ASCII URLs while preserving readability for CJK and other scripts.

Handling Specific Scripts

Accented Latin Characters

Use Unicode Normalization Form D (NFD) to decompose accented characters, then strip combining marks:

function removeAccents(text) {
  return text.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
}

removeAccents('café')  // 'cafe'
removeAccents('Zürich')  // 'Zurich'

This handles French, German, Spanish, Portuguese, and most European languages.

CJK Characters

Chinese, Japanese, and Korean characters don't decompose via NFD. Decide per-language:

  • Chinese: Preserve Unicode for readability (北京旅游)
  • Japanese: Some sites use romaji (tokyo-kanko), others preserve kana/kanji (東京観光)
  • Korean: Hangul can be preserved (서울-여행) or transliterated (seoul-yeohaeng)

Google has stated that CJK URLs work fine for indexing. Preserve the script when your audience reads it natively.

Arabic and Hebrew (RTL)

Right-to-left scripts in URLs can cause display confusion. Browsers handle the encoding, but the visual representation in the address bar may look odd. Test in multiple browsers.

Recommendation: Transliterate Arabic and Hebrew to ASCII unless your audience strongly prefers native script URLs.

Cyrillic

Russian site owners commonly transliterate to ASCII (московский-путеводительmoskovskiy-putevoditel). This avoids visual ambiguity with Latin characters (Cyrillic "а" looks identical to Latin "a") which can enable homograph phishing.

SEO Considerations

  • Google handles both ASCII and Unicode slugs — no ranking penalty for either approach
  • Use hreflang tags to associate translated URLs with their language
  • Keep slugs consistent — the same content should always generate the same slug
  • Avoid mixing scripts in a single slug — don't combine Latin and CJK characters in one URL segment
  • Shorter slugs perform better — transliteration produces shorter URLs than percent-encoded Unicode

Normalization Pipeline

A robust slug generator follows these steps:

  1. Trim leading and trailing whitespace
  2. Normalize to NFC (composed form) for consistent representation
  3. Locale-specific processing — transliterate or preserve based on script
  4. Lowercase for Latin scripts (skip for CJK where case doesn't apply)
  5. Replace separators — spaces and underscores to hyphens
  6. Strip remaining non-word characters (regex: [^\p{L}\p{N}-])
  7. Collapse multiple hyphens into one
  8. Trim leading and trailing hyphens

Key Takeaways

  • Multilingual slugs require choosing between transliteration, Unicode preservation, or a hybrid approach
  • Transliterate Latin-script accents using NFD normalization and combining mark removal
  • Preserve CJK characters for native audiences — Google indexes them correctly
  • Transliterate Arabic and Hebrew to avoid RTL display issues
  • Use hreflang tags to link translated pages across languages
  • Follow a consistent normalization pipeline to generate stable, repeatable slugs
  • Avoid mixing scripts in a single slug segment

Try It Yourself

Generate URL slugs for any language instantly with our free Slug Generator. Paste your title, choose a strategy, and get a clean, SEO-friendly slug in one click.