Configurer la traduction avec expo-localization dans Expo

Par coderoe · 5 min de lecture

React Native
Configurer la traduction avec expo-localization dans Expo

Dans ce tutoriel, nous allons configurer un système de traduction multilingue dans une application Expo React Native, en utilisant expo-localization pour détecter automatiquement la langue du système et gérer les traductions.

1. Installer les dépendances nécessaires

Installe toutes les dépendances nécessaires pour le système de traduction :

# Détection automatique de la langue
npx expo install expo-localization

# Système de traduction
npm install i18next react-i18next

# Stockage persistant
npx expo install @react-native-async-storage/async-storage

# Icônes (optionnel)
npm install lucide-react-native

2. Créer la structure des dossiers de traduction

Crée une structure de dossiers pour organiser tes traductions par langue :

translation/
├── index.ts
└── locales/
    ├── fr-FR.json
    └── en-US.json

3. Créer les fichiers de traduction

  • Crée le fichier translation/locales/fr-FR.json pour le français :
{
  "welcome": "Bonjour"
}
  • Crée le fichier translation/locales/en-US.json pour l'anglais :
{
  "welcome": "Hello"
}

4. Configurer le système de traduction

Crée le fichier translation/index.ts avec la configuration complète utilisant i18next et react-i18next :

import AsyncStorage from "@react-native-async-storage/async-storage";
import * as Localization from "expo-localization";
import i18n from "i18next";
import { initReactI18next } from "react-i18next";

import enUS from './locales/en-US.json';
import frFR from "./locales/fr-FR.json";

const resources = {
    "fr-FR": { translation: frFR },
    'en-US': { translation: enUS },
};

const initI18n = async () => {
    try {
        let savedLanguage = await AsyncStorage.getItem("language");

        if (!savedLanguage) {
            savedLanguage = Localization.getLocales()[0]?.languageTag || "en-US";
        }

        i18n.use(initReactI18next).init({
            resources,
            lng: savedLanguage,
            fallbackLng: "en-US",
            interpolation: {
                escapeValue: false,
            },
        });
    } catch (error) {
        console.error("Erreur lors de l'initialisation de i18n:", error);
        // Fallback en cas d'erreur
        i18n.use(initReactI18next).init({
            resources,
            lng: "en-US",
            fallbackLng: "en-US",
            interpolation: {
                escapeValue: false,
            },
        });
    }
};

initI18n();

export default i18n;

Explications du code :

  • Détection automatique : Localization.getLocales()[0]?.languageTag détecte la langue du système au démarrage
  • Sauvegarde persistante : AsyncStorage sauvegarde le choix de langue de l'utilisateur
  • Fallback robuste : En cas d'erreur, l'application utilise l'anglais par défaut
  • i18next : Utilise la bibliothèque standard pour l'internationalisation avec React

5. Utiliser les traductions dans votre application

Crée ton composant principal app/index.tsx :

import { useState } from "react";
import { Text, View, TouchableOpacity, StyleSheet } from "react-native";

import AsyncStorage from "@react-native-async-storage/async-storage";
import { useTranslation } from "react-i18next";
import { Check } from "lucide-react-native";

import i18n from "@/translation";

export default function Index() {
  const { t } = useTranslation();
  const [currentLanguage, setCurrentLanguage] = useState(i18n.language);

  const languages = [
    { code: "en-US", name: "English" },
    { code: "fr-FR", name: "Français" },
  ];

  const changeLanguage = async (lng: string) => {
    try {
      await AsyncStorage.setItem("language", lng);
      i18n.changeLanguage(lng);
      setCurrentLanguage(lng);
    } catch (error) {
      console.error("Erreur lors de la sauvegarde de la langue:", error);
    }
  };

  return (
    <View style={styles.container}>
      <Text style={styles.text}>{t("welcome")}</Text>
      <View style={styles.containerButton}>
        {languages.map((lang) => (
          <TouchableOpacity
            key={lang.code}
            onPress={() => changeLanguage(lang.code)}
            style={styles.button}
            activeOpacity={0.8}
          >
            <Text style={styles.buttonText}>{lang.name}</Text>
            {currentLanguage === lang.code && <Check />}
          </TouchableOpacity>
        ))}
      </View>
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
    gap: 20,
  },
  text: {
    fontSize: 32,
    fontWeight: "bold",
  },
  containerButton: {
    width: "100%",
    gap: 1,
  },
  button: {
    height: 60,
    width: "100%",
    backgroundColor: "#fff",
    flexDirection: "row",
    alignItems: "center",
    justifyContent: "space-between",
    paddingHorizontal: 20,
  },
  buttonText: {
    fontSize: 20,
    fontWeight: "500",
    textAlign: "center",
    color: "#000",
  },
});

Comment ça fonctionne :

  1. Hook useTranslation : const { t } = useTranslation() fournit la fonction de traduction
  2. State local : currentLanguage force le re-render quand la langue change
  3. Utilisation : t("welcome") retourne "Bonjour" en français ou "Hello" en anglais
  4. Sauvegarde persistante : AsyncStorage sauvegarde le choix de langue
  5. Interface utilisateur : Boutons avec indicateur visuel (Check) pour la langue active

6. Tester le changement de langue

Lance ton projet avec :

npx expo start

Ajouter plus de traductions :

Pour ajouter de nouvelles traductions, ajoute simplement de nouvelles clés dans tes fichiers JSON :

translation/locales/fr-FR.json :

{
  "welcome": "Bonjour",
  "hello": "Salut",
  "myNewKey": "Ma nouvelle traduction"
}

translation/locales/en-US.json :

{
  "welcome": "Hello",
  "hello": "Hi",
  "myNewKey": "My new translation"
}

Puis utilise-la dans ton code :

<Text>{t("myNewKey")}</Text>

Ajouter une nouvelle langue :

  1. Crée un nouveau fichier translation/locales/es-ES.json pour l'espagnol
  2. Ajoute les traductions
  3. Importe-le dans translation/index.ts :
import esES from './locales/es-ES.json';

const resources = {
    "fr-FR": { translation: frFR },
    'en-US': { translation: enUS },
    'es-ES': { translation: esES },
};
  1. Ajoute la langue dans ton composant :
const languages = [
  { code: "en-US", name: "English" },
  { code: "fr-FR", name: "Français" },
  { code: "es-ES", name: "Español" },
];

C'est tout ! Tu as maintenant un système de traduction complet et type-safe pour ton application Expo.