0017. Ship English and Hindi; right-to-left is a switch per language
Context
Section titled “Context”The template shipped English and Arabic. Arabic was the demo language because it exercises the hard cases at once: a right-to-left layout and six plural forms. No decision named it, and it isn’t a language the maintainer reads, so its strings couldn’t be reviewed, and a right-to-left alignment bug on iOS went unnoticed until screenshots were taken.
The maintainer wants the template to stay multilingual with a second language they can check, and to keep right-to-left support ready for apps that need it.
Decision
Section titled “Decision”- Languages: English and Hindi (
hi, shown as “हिन्दी”). Hindi is a second script (Devanagari) with its own plural rule (0 and 1 are “one”) and relative-time phrases, so it still tests that nothing is hard-coded to English. - Right-to-left is a flag on each language in
LANGUAGES(src/shared/i18n/index.ts). No shipped language sets it. Adding Arabic, Hebrew, Persian or Urdu is a locale file, an entry withrtl: trueand its relative-time data insrc/shared/lib/format.ts. The direction switch, the restart prompt in Settings, mirrored icons andstart/endlayout stay in the code. - Tests keep right-to-left working without an RTL language:
applyDirectionis tested with the flag (src/shared/i18n/i18n.test.ts), directional icons are tested under a right-to-left runtime (src/shared/ui/primitives/Icon.test.tsx), and every shipped language must have every English key. - Lint rejects physical sides in styles (
marginLeft,paddingRight,left,borderLeftWidth…) andtextAlign: 'left' | 'right', so layouts mirror when a right-to-left language is added. - The generator and
pnpm strip-exampleswork on every file insrc/shared/i18n/locales, so adding a language needs no script changes.
Consequences
Section titled “Consequences”- Right-to-left is no longer seen on a device in the demo. Unit tests and the lint rule cover the code, but an app that adds an RTL language must check it on iOS and Android. The open iOS alignment issue (text not following the RTL layout) has to be fixed before such an app ships.
- Switching between English and Hindi takes effect at once, with no restart, so text has to follow a
language change while the app runs. Formatted dates and times now come from
useFormat(), because the React Compiler cached plainformatRelative(date)calls in the old language; lint enforces it. Screen titles translated once at startup show the same problem and still need fixing. - Hindi strings use everyday app Hindi with common loan words (ऐप, ईमेल, पासवर्ड, सिंक). An app that ships Hindi should still have them reviewed for its audience.
Alternatives considered
Section titled “Alternatives considered”- Keep Arabic: covers right-to-left on a device, but nobody on the project can review it.
- English only, with a hidden language picker: simpler, but the template would stop showing that every string is translated and that formatting follows the language.
- Keep Arabic’s locale file unused as a sample: it would drift from
en.jsonwithout a test.
Made by Praveen Singh, Senior React Native engineer