Internationalization & Localization
i18n = building software so it can adapt; l10n = the adaptation itself. Read this before the first hardcoded string ships, not after.
Locale ≠ language
- A locale bundles language + region + formatting conventions (
de-AT,pt-BR,zh-Hant-TW), and these vary independently: Swiss German formats numbers differently than German German; US and UK English disagree on dates. Let users set language and region separately; never infer language from IP (a traveler in Tokyo is not a Japanese reader) — default fromAccept-Language/OS locale, make switching easy, persist it.
Text expansion & contraction
- Translated text changes length; the shorter the source string, the larger the relative growth. IBM's oft-cited figures (reproduced in W3C's "Text size in translation"): strings under ~10 characters can grow 100–200% — up to 300% is unsurprising for tiny labels — while paragraph-length text grows a gentler ~30%. English→Chinese contracts in character count but each glyph is denser and needs taller lines.
- Design consequences: never fix widths/heights to English strings; let buttons, tabs, and labels grow (min-width, not width); test German and Finnish for width, Chinese for density; beware unwrappable German compounds ("Eingabeverarbeitungsfunktionen"); truncation with full text on focus/hover is a last resort only.
RTL and bidirectional text
- Arabic, Hebrew, Persian, Urdu are right-to-left. Mirroring the layout is
necessary but it is not a blanket horizontal flip. Per Material
Design's bidirectionality guidance and Apple's HIG "Right to left" page:
- Mirror: reading order, navigation (back points right), progress bars, sliders, breadcrumbs, forward/back icons, icon+label layout.
- Don't mirror: media playback controls and scrubbers (play points right — the convention is tape/time direction, not reading direction), clocks and clockwise arrows (refresh/redo), musical notes, checkmarks, numbers (digits stay LTR inside RTL text), logos, code snippets.
- Bidi text mixes directions (an Arabic sentence containing an English
brand name); use logical CSS properties (
margin-inline-start, notmargin-left) and bidi isolation (<bdi>,unicode-bidi: isolate). Test with real RTL content — flipped English hides bidi bugs.
CJK typography basics
- Chinese and Japanese have no spaces between words; breaks are allowed between most characters but forbidden around certain punctuation (Japanese kinsoku shori) — rely on the platform line-breaking engine, never on space-based wrapping or truncation.
- Italics are not a native CJK convention — emphasis uses emphasis dots, corner brackets 「」, or weight; synthetic oblique CJK reads as broken.
- Font-size parity: CJK glyphs are denser; at equal point size they read
smaller and need more line height (≈1.7–2.0 vs ≈1.5 for Latin). No case
exists, so ALL-CAPS tricks don't transfer. Han unification means the
same codepoint renders differently in zh-Hans/zh-Hant/ja — declare
langcorrectly on every page/element.
Names, addresses, phones
- W3C's "Personal names around the world" (Ishida): family-name-first orders (Hungarian, Chinese, Japanese), Icelandic patronymics (no family name to sort by), single names (Indonesian), multiple family names (Spanish), no universal middle name. Prescription: prefer one full-name field (plus optional "what should we call you?") over first/last; never require a last name; allow spaces, apostrophes, hyphens, any script.
- Addresses: field order, state/province presence, and postcode formats
vary by country (Japan orders large→small; some countries lack
postcodes). Ask country first, then render a country-appropriate form
(Google's
libaddressinputdataset encodes per-country formats). - Phones: store E.164 (
+81…), display localized; accept any punctuation the user types; validate with libphonenumber, not a homemade regex.
Dates, times, numbers, currency
- Never hand-format. Use the platform's locale APIs — ECMAScript
Intl.DateTimeFormat/NumberFormat, ICU on native — which draw on Unicode CLDR data. Hand-formatting gets decimal commas (1.234,56), digit grouping (Indian lakh: 12,34,567), symbol position, and calendar systems wrong. - Avoid ambiguous numeric dates: 03/04/05 is three different days across locales; a spelled-out month (4 Mar 2026) survives anywhere. Week start and 12h/24h clocks are locale settings, not design choices.
- Currency formatting follows the display locale, but the currency never converts implicitly — show the code when audiences mix ($ is ambiguous across USD/CAD/AUD/MXN).
Icons, imagery, color across cultures
- Gesture icons are risky: thumbs-up, the "OK" ring, and pointing hands offend in some regions — hand gestures don't travel. Idiom icons (piggy bank, owl-for-wisdom) and US-only metaphors (mailbox with flag) break too. Prefer concrete objects; test icon comprehension per market.
- Color semantics shift: red = danger/debt in the West but luck in China (and Chinese stock tickers use red for up); white = mourning in parts of East Asia. See Color in Interface Design; never rely on color alone.
Engineering patterns that make or break l10n
- No string concatenation: "You have " + n + " items" is untranslatable — word order differs, and pluralization isn't binary. CLDR defines up to six plural categories (zero/one/two/few/many/other — Arabic uses all six; Russian's "few" covers 2–4). Use ICU MessageFormat (or Fluent) with named placeholders and plural/select syntax; give translators context comments. Don't reuse one string in two UI spots (English noun/verb homonyms split in other languages).
- Locale-aware sorting: binary/ASCII sort misorders almost every
language (ä sorts after z in Swedish but with a in German). Use ICU
collation /
Intl.Collator, and accent-insensitive search where users expect it. - Pseudo-localization: test before translating by piping strings through a pseudo-locale — accents ([Àççôûñţ Šéţţîñĝš]), +40% padding, bracket delimiters. Instantly reveals hardcoded strings, clipping, and concatenation. Built into Android and iOS — run it in CI.
Cultural adaptation beyond translation
- Localize content, not just strings: holidays and campaigns (Lunar New Year, Ramadan, Diwali — hemispheres flip seasons), imagery, placeholder names, legal text, units.
- Payment methods decide checkout conversion: cards are not the global default — iDEAL (NL), UPI (India), Pix (Brazil), Alipay/WeChat Pay (China), cash-on-delivery across much of MENA and Southeast Asia. Offering only card + PayPal reads as "not built for you."
- Local competitors set expectations (East Asian e-commerce density is a preference, not a flaw); run market-specific usability tests rather than assuming the home-market design generalizes.
Sources
- W3C Internationalization (w3.org/International) — "Text size in
translation" (IBM expansion figures), "Personal names around the world"
(Ishida), bidi and
langarticles; JLReq/CLReq text-layout requirements. - Material Design 3 — "Bidirectionality & RTL" (m3.material.io); Apple HIG — "Right to left" (developer.apple.com).
- Unicode CLDR — plural rules, collation, locale data (cldr.unicode.org);
ICU MessageFormat; ECMA-402 (
Intl). - Google
libaddressinputandlibphonenumber; ITU E.164. - CJK line-height figures are working conventions from practice, not standards — validate per typeface and market.