CodePark/ questions / i18n & accessibility at scale
START PRACTICINGPRACTICE
Frontend question · Frontend system design › i18n & accessibility at scale

How would you architect internationalisation for a large app supporting 30 languages, including RTL?

{
  "cart.items": "{count, plural, =0 {Your cart is empty} one {# item} other {# items}}",
  "greeting": "Hello, {name}!"
}

Keep all text in translation catalogues using ICU messages, lazy load each language, format with Intl, and use CSS logical properties for RTL.

Messages: all user-facing strings live in catalogues, keyed by id. They use ICU MessageFormat, a standard syntax for messages with variables. It handles plurals, gender and select rules per language. Never build strings by concatenation. Translators work in a translation management system. CI (the automatic checks on each change) extracts new keys. It fails when keys are missing for required locales (languages and regions).

Loading: each locale's catalogue is split per route or feature and lazy loaded. So users download only their own language. The locale is chosen in this order:

  • the URL path, which is good for SEO and sharing
  • then a saved preference
  • then the Accept-Language header

The page is rendered on the server in that locale, to avoid a flash of the wrong language.

Formatting: dates, numbers, currencies, relative times and lists use the Intl APIs with the active locale. Time zones are explicit.

RTL (right-to-left languages like Arabic): set dir on html. Use CSS logical properties, such as margin-inline-start and inset-inline-end, so layouts mirror automatically. Directional icons, like arrows, flip. Logos and media do not.

Layout: allow for text that grows 30 to 40 percent longer after translation. Test with pseudo-localisation. It replaces the text with longer, accented fake text, to find layout bugs early.

  • Use ICU messages with plural rules, never concatenation.
  • Lazy load one catalogue per locale.
  • Put the locale in the URL and render it on the server.
  • Use Intl for dates, numbers and currency.
  • Use the dir attribute and CSS logical properties for RTL.