i18next

Detecting Locale with i18next and react-i18next

i18next 361,756 (https://github.com/i18next/i18next 8,637 ) (MIT) keeps translations as JSON per language and looks them up by key; react-i18next 10,046 adds the useTranslation() hook, which re-renders when the language changes; and expo-localization's getLocales() returns the user's preferred locales, best first, each with a languageCode, languageTag and textDirection (installed with npx expo install). BookNest initializes i18next once, imported at the top of the root layout:

src/i18n/index.ts: choosing the language (excerpt)TypeScript
const [locale] = getLocales();
i18n.use(initReactI18next).init({
  resources: { en: { translation: en }, es: { translation: es }, ar: { translation: ar } },
  lng: locale?.languageCode ?? 'en',
  fallbackLng: 'en',                                   // missing keys fall back to English
  interpolation: { escapeValue: false },               // React already escapes text
});

Screens call t('cart.total', { total }) instead of hard-coding "Total". Plurals get suffixed keys: English needs items_one and items_other, Arabic six forms, from _zero to _other. Android 13 and later let users pick a language per app, which a script can do too: adb -s emulator-5554 shell cmd locale set-app-locales com.anonymous.booknest --locales es-ES. The app's next start logged locale es-ES | language es | RTL false | text direction ltr.

To offer that choice in the system settings, list the languages in the expo-localization plugin's supportedLocales option.