Add a New Language
Step-by-step guide to add a new language to your app.
Step 1: Create Translation File
Create a new JSON file for your language:
bash
# Create French translation file
touch src/i18n/locales/fr.jsonsrc/i18n/locales/fr.json
{
"common": {
"welcome": "Bienvenue",
"loading": "Chargement...",
"error": "Une erreur s'est produite",
"save": "Enregistrer",
"cancel": "Annuler",
"delete": "Supprimer",
"edit": "Modifier"
},
"auth": {
"login": "Connexion",
"logout": "Déconnexion",
"email": "E-mail",
"password": "Mot de passe",
"forgotPassword": "Mot de passe oublié ?",
"noAccount": "Vous n'avez pas de compte ?",
"signUp": "S'inscrire"
},
"home": {
"title": "Accueil",
"greeting": "Bonjour, {{name}} !",
"taskCount": "Vous avez {{count}} tâche",
"taskCount_plural": "Vous avez {{count}} tâches"
}
}Make sure all keys match your existing language files!
Step 2: Register Language
Add the language to i18n configuration:
src/i18n/index.ts
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import * as Localization from 'expo-localization';
// Import all language files
import en from './locales/en.json';
import pt from './locales/pt.json';
import es from './locales/es.json';
import fr from './locales/fr.json'; // ✅ Add this
const resources = {
en: { translation: en },
pt: { translation: pt },
es: { translation: es },
fr: { translation: fr }, // ✅ Add this
};
i18n
.use(initReactI18next)
.init({
resources,
lng: Localization.locale.split('-')[0],
fallbackLng: 'en',
interpolation: {
escapeValue: false,
},
});
export default i18n;Step 3: Update Language Selector
Add the language option to your UI:
typescript
const languages = [
{ code: 'en', name: 'English', flag: '🇺🇸' },
{ code: 'pt', name: 'Português', flag: '🇧🇷' },
{ code: 'es', name: 'Español', flag: '🇪🇸' },
{ code: 'fr', name: 'Français', flag: '🇫🇷' }, // ✅ Add this
];
export function LanguageSelector() {
const { i18n } = useTranslation();
return (
<View className="gap-2">
{languages.map((lang) => (
<Pressable
key={lang.code}
onPress={() => i18n.changeLanguage(lang.code)}
className={cn(
'p-4 rounded-lg flex-row items-center gap-3',
i18n.language === lang.code
? 'bg-blue-500'
: 'bg-slate-200 dark:bg-slate-700'
)}
>
<Text className="text-2xl">{lang.flag}</Text>
<Text
className={cn(
'font-semibold',
i18n.language === lang.code
? 'text-white'
: 'text-slate-900 dark:text-white'
)}
>
{lang.name}
</Text>
</Pressable>
))}
</View>
);
}Step 4: Add Date Locale (Optional)
For date formatting with date-fns:
bash
npm install date-fnstypescript
import { format } from 'date-fns';
import { enUS, ptBR, es, fr } from 'date-fns/locale';
const locales = {
en: enUS,
pt: ptBR,
es,
fr, // ✅ Add this
};
export function useDateFormatter() {
const { i18n } = useTranslation();
const locale = locales[i18n.language as keyof typeof locales];
return {
formatDate: (date: Date, pattern: string = 'PP') =>
format(date, pattern, { locale }),
};
}Step 5: Update TypeScript Types (Optional)
For type safety, update your i18n types:
src/i18n/types.ts
import en from './locales/en.json';
export type TranslationKeys = typeof en;
export type SupportedLanguage = 'en' | 'pt' | 'es' | 'fr'; // ✅ Add 'fr'
declare module 'react-i18next' {
interface CustomTypeOptions {
defaultNS: 'translation';
resources: {
translation: TranslationKeys;
};
}
}Validation Checklist
✅ All keys translated
Make sure every key from your base language (en) is present
✅ Pluralization forms
Add _plural variants where needed
✅ Test UI layout
Some languages have longer words - ensure UI doesn't break
✅ RTL support (if needed)
For Arabic/Hebrew, enable RTL layout support
RTL Languages (Arabic, Hebrew)
For right-to-left languages:
typescript
import { I18nManager } from 'react-native';
// In your app initialization
useEffect(() => {
const rtlLanguages = ['ar', 'he'];
const isRTL = rtlLanguages.includes(i18n.language);
if (I18nManager.isRTL !== isRTL) {
I18nManager.forceRTL(isRTL);
// Restart app for changes to take effect
// RNRestart.Restart();
}
}, [i18n.language]);Testing
Test your new language:
typescript
// In your app
import { useTranslation } from 'react-i18next';
export function TestScreen() {
const { i18n, t } = useTranslation();
return (
<View className="p-4">
<Text>Current language: {i18n.language}</Text>
<Pressable onPress={() => i18n.changeLanguage('fr')}>
<Text>Switch to French</Text>
</Pressable>
<Text>{t('common.welcome')}</Text>
<Text>{t('auth.login')}</Text>
</View>
);
}Tools & Tips
Translation Tools
- i18n-ally - VS Code extension for managing translations
- Crowdin - Collaborative translation platform
- Lokalise - Translation management system
Best Practices
✓
Keep base language (en) as source of truth
✓
Use professional translators for production apps
✓
Test with native speakers
✓
Consider cultural differences (dates, currency, images)
You can also use tools like Google Translate API to auto-translate strings during development.