Slug Generation for Multilingual URLs: Best Practices
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:
| Original | Transliterated | Slug |
|---|---|---|
| Café au lait | Cafe au lait | cafe-au-lait |
| München | Munchen | munchen |
| Szczęść Boże | Szczesc Boze | szczesc-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
Strategy 2: Preserve Unicode (Recommended for non-Latin)
Keep the original characters in the slug. The browser percent-encodes them automatically:
| Language | Title | Slug |
|---|---|---|
| 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
hreflangtags 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:
- Trim leading and trailing whitespace
- Normalize to NFC (composed form) for consistent representation
- Locale-specific processing — transliterate or preserve based on script
- Lowercase for Latin scripts (skip for CJK where case doesn't apply)
- Replace separators — spaces and underscores to hyphens
- Strip remaining non-word characters (regex:
[^\p{L}\p{N}-]) - Collapse multiple hyphens into one
- 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
hreflangtags to link translated pages across languages - Follow a consistent normalization pipeline to generate stable, repeatable slugs
- Avoid mixing scripts in a single slug segment
Related Guides
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.