Internationalization
How to add internationalization to your app.
Caracal ships with a basic internationalization (i18n) setup using expo-localization and i18next. Everything i18n-related lives in src/lib/i18n/.
Adding a New Language
The demo app supports English and Arabic (RTL) out of the box. To add another language:
- Create a new translation JSON file in
src/translations/. - Register it in
src/lib/i18n/resources.ts.
import en from '@/translations/en.json';
import ar from '@/translations/ar.json';
// import fr from '@/translations/fr.json';
export const resources = {
en: { translation: en },
ar: { translation: ar },
// fr: { translation: fr },
};Anything related to internationalization lives in src/lib/i18n/.
Using Translations in Your App
useTranslation hook
Use the useTranslation hook from react-i18next to get the t translation function:
import React from 'react';
import { useTranslation } from 'react-i18next';
import { Text } from '@/components/ui';
export const Foo = () => {
const { t } = useTranslation();
return <Text className="text-center">{t('settings.language')}</Text>;
};tx prop shorthand
The Text component from @/components/ui accepts a tx prop as a shorthand, so you can skip importing useTranslation for simple cases:
import React from 'react';
import { Text } from '@/components/ui';
export const Foo = () => {
return <Text className="text-center" tx="settings.language" />;
};useSetLanguage hook
Use useSetLanguage from src/lib/i18n/utils.tsx to read and change the active language at runtime.
This hook:
- Returns the currently selected language and a setter function
- Persists the selection to device storage via MMKV so the preference is restored on next launch
- Applies extra RTL configuration for right-to-left languages when switching
Robust Translations
TypeScript Support
Caracal adds TypeScript definitions for translation keys, giving you autocomplete and compile-time errors when you use an incorrect key. If you reference a key that doesn't exist in the translation files, TypeScript will flag it immediately.
ESLint Rules
Caracal enforces translation file consistency via eslint-plugin-i18n-json and a custom i18next validation script. These rules run as a pre-commit hook whenever translation files change.
The checks enforce:
- All resource files have identical keys (no missing translations)
- Keys are sorted consistently
- JSON syntax is valid