CASE STUDY

Runtime Localization System (i18n)

3 min read·483 words·Intermediate

Asked at

1 candidate report in Apr 2026

How to use this case study

SDE-2 / Mid

Explain string keys with translations per locale, variables in messages, and fallback when a translation is missing.

SDE-3 / Senior

Go deeper on plural and gender rules (ICU MessageFormat), locale fallback chains, delivering translation bundles via CDN with versioning, and updates without redeploying.

Staff / Principal

Discuss the translation workflow (extraction, translators, review), pseudo-localization testing, RTL layouts, and performance on clients.


0) Problem Restatement

Adobe asked: design a localization system for a product released in dozens of countries. Every user-facing string must resolve by locale at runtime, support variables ("Hello, {name}"), follow language-specific plural rules ("1 file" / "2 files", and languages with more plural forms like Polish or Arabic), fall back safely when a translation is missing, and allow updating translations without redeploying the app.


1) Core Concepts

  • Message keys: code never contains English text directly. It uses keys: t("files.deleted", { count: 3 }).
  • Catalogs: per locale, a map key → message:

  en:    files.deleted = "{count, plural, one {# file deleted} other {# files deleted}}"
  pl:    files.deleted = "{count, plural, one {Usunięto # plik} few {Usunięto # pliki} many {Usunięto # plików} other {Usunięto # pliku}}"
  

These use ICU MessageFormat, the standard syntax for variables, plurals, gender and selects. The plural categories (one, few, many, other) come from CLDR data per language.

  • Formatting: dates, numbers and currencies use locale-aware formatters (Intl.DateTimeFormat, Intl.NumberFormat), never string concatenation.


2) Fallback Chain

When a key is missing in the user's locale, try: fr-CA → fr → en (the default). If it's still missing (a bug), show the key or the English text and log it (monitoring missing translations), never a blank.


3) Architecture

Architecture Diagram

flowchart LR
    DEV["Developers - add keys in code"] --> EXT["Extraction in CI - new/changed keys"]
    EXT --> TMS["Translation management system"]
    TMS --> TR["Translators / vendors + review"]
    TR --> TMS
    TMS -->|"publish"| BLD["Bundle builder - per locale, validated"]
    BLD --> CDN[("CDN - versioned bundles")]
    APP["Apps - web, mobile, desktop"] -->|"fetch bundle for locale"| CDN
    APP --> LIB["i18n runtime - ICU format + fallback"]
  • Extraction: CI scans the code for keys and source strings, and sends new or changed ones (with context screenshots and comments) to the translation management system.
  • Bundles: per locale (and per app module, to keep them small), with a content hash in the name. The published manifest lists the latest bundle per locale.
  • Runtime loading: the app ships with a built-in default bundle (so it works offline and at first launch), then fetches the latest bundle version from the CDN, caches it, and uses it on the next screen or launch. That's how translations update without redeploying.
  • Validation before publish: ICU syntax is valid, variables match the source (a translation mustn't drop {name}), and length limits are respected for UI elements.


4) Quality and UX

  • Pseudo-localization in testing: replace strings with accented, longer text ("[Ŝéţţîñĝš !!!]") to catch hard-coded strings and layout overflow early.
  • Right-to-left languages (Arabic, Hebrew): mirror the layouts (CSS logical properties), and test them.
  • Locale detection: the user's setting first, then the OS or browser language, then region. Keep the locale separate from the country (prices and legal content may depend on the country).
  • Performance: load only the needed locale and modules, and cache compiled message formatters.


5) Wrap-Up

Replace UI text with message keys and resolve them at runtime from per-locale catalogs written in ICU MessageFormat (variables, CLDR plural and gender rules), with locale-aware date and number formatting and a fr-CA → fr → en fallback chain that logs misses. Run a CI extraction to translation management to validated bundle pipeline, publish versioned bundles to a CDN that apps fetch and cache (with a built-in default), and ensure quality with pseudo-localization, RTL support and variable checks.

More Case Studies

Practice with a Mock Interview

Apply what you learned in a live system design mock interview with our AI interviewer.

Start System Design Interview →