isation dans React avec react-i18next
Quand une application web s'adresse à un public réparti sur plusieurs pays, la gestion des langues devient un sujet central. La bibliothèque react-i18next s'est imposée comme une solution de référence dans l'écosystème React pour gérer les traductions, basculer entre les langues et traiter les règles de pluralisation. Elle s'appuie sur i18next, un framework de traduction robuste utilisé dans de nombreux environnements JavaScript.
Contrairement à un simple remplacement par dictionnaire, react-i18next s'intègre naturellement au modèle de composants React grâce à un hook dédié et à des composants prêts à l'emploi. L'outil permet de structurer les ressources par namespaces, de charger les traductions à la volée et de gérer des cas complexes comme les langues genrées ou le formatage des dates selon les conventions locales.
Ce guide décrit l'ensemble du flux d'implémentation, depuis la configuration initiale jusqu'aux fonctionnalités avancées. Que vous mainteniez un projet personnel ou une application de production à grande échelle, les patterns présentés vous aideront à bâtir une base multilingue pérenne et maintenable.
Installation et configuration initiale
La première étape consiste à installer les paquets nécessaires. Vous aurez besoin d'i18next et de react-i18next, ainsi qu'un plugin pour détecter automatiquement la langue de l'utilisateur. Dans un projet standard, exécutez npm install i18next react-i18next i18next-browser-languagedetector. Le plugin de détection lit la langue du navigateur et toute préférence précédemment enregistrée dans le localStorage.
La configuration se centralise généralement dans un fichier dédié, souvent nommé i18n.js. Vous importez i18next, le plugin de détection et les ressources de traduction, puis vous appelez i18next.use(...).init({...}) avec des options comme fallbackLng, interpolation et l'ordre de détection. La langue de repli garantit que l'application reste fonctionnelle même lorsqu'une traduction spécifique manque.
Pour les projets TypeScript, il est possible d'étendre le module i18next afin d'obtenir un typage fort sur les clés de traduction. Cette étape demande un fichier .d.ts personnalisé qui décrit la forme des ressources. Bien qu'elle ajoute un peu de travail en amont, elle se rentabilise rapidement en détectant les clés manquantes à la compilation et en améliorant l'expérience développeur avec l'autocomplétion.
Organisation des fichiers de traduction
Une pratique répandue consiste à regrouper les traductions par fonctionnalité ou par page. Chaque namespace correspond à un fichier JSON contenant des paires clé-valeur dans chaque langue prise en charge. Par exemple, un fichier home.json regroupe les chaînes de la page d'accueil et un fichier dashboard.json celles de l'espace authentifié.
La structure de dossiers suit généralement une convention du type locales/en/common.json, locales/fr/common.json, et ainsi de suite. Cette disposition facilite l'ajout de nouvelles langues ou la délégation du travail à des contributeurs externes. Pour les projets qui manipulent des volumes importants ou partagent les ressources entre plusieurs applications, il devient pertinent de stocker les traductions côté serveur. Vous pouvez à cet effet comparer les bases de données orientées document et relationnelles afin de choisir la solution la mieux adaptée à votre backend multilingue.
Le chargement paresseux des namespaces s'avère utile lorsque la taille du bundle initial compte. Au lieu d'importer tous les fichiers au démarrage, vous les chargez à la demande lorsque l'utilisateur accède à une section précise. react-i18next expose le comportement Suspense et la fonction ready à cet effet, pour des transitions fluides sans bloquer l'interface.
Utilisation du hook useTranslation dans les composants
Le hook useTranslation renvoie la fonction de traduction t ainsi que l'instance i18n. Vous écrivez const { t, i18n } = useTranslation() en haut de votre composant, puis vous remplacez les chaînes codées en dur par t('key'). Le hook s'abonne aux changements de langue, donc tout composant qui l'utilise se met à jour automatiquement lors d'un changement.
Pour les contenus plus complexes, le composant Trans accepte des chaînes contenant des balises JSX. C'est pratique lorsque les traducteurs doivent inclure des liens ou des mises en forme qui ne peuvent pas s'exprimer en texte brut. Le composant gère la pluralisation, l'interpolation et même le HTML de base de manière sécurisée, sans recourir à dangerouslySetInnerHTML.
Pour les éléments partagés comme l'en-tête, le pied de page ou les menus, il est commode de charger un namespace commun une seule fois et de le réutiliser dans toute l'application. Vous pouvez passer un tableau de namespaces au hook, par exemple useTranslation(['common', 'header']), puis accéder aux clés avec t('header:logo_alt') grâce au préfixe du namespace.
Pluriel, interpolation et formats spécifiques
La traduction dépasse rarement le simple remplacement de mots. Les langues possèdent des règles de pluriel distinctes, et react-i18next prend en charge la syntaxe standard d'i18next. Au lieu de définir des clés séparées pour le singulier et le pluriel, vous écrivez t('item', { count: n }) et vous fournissez une seule clé avec les variantes _one et _other dans le fichier JSON.
L'interpolation permet d'insérer des valeurs dynamiques dans les chaînes traduites. Vous définissez des emplacements comme "Bonjour, {{name}}" et vous passez à la fonction t un objet contenant les valeurs correspondantes. Cette approche laisse les traducteurs maîtres de la structure des phrases tout en autorisant l'injection de données issues de la logique applicative.
Au-delà du texte, les dates, les nombres et les devises nécessitent un formatage tenant compte de la locale. L'API Intl intégrée aux navigateurs modernes couvre la plupart des besoins, et vous pouvez la combiner avec la langue active issue de i18n.language. Pour la conversion de devises ou d'unités, des bibliothèques comme dinero ou dayjs ajoutent un confort appréciable, notamment pour les chiffres arabes ou les écritures de droite à gauche.
Comparaison des bibliothèques d'internationalisation
| Critère | react-i18next | react-intl | FormatJS |
|---|---|---|---|
| Taille du bundle | Moyenne | Moyenne à élevée | Moyenne |
| API principale | Hook useTranslation | Composants FormattedMessage | Composants et hooks |
| Gestion du pluriel | Via clé avec suffixes | Syntaxe CLDR | Syntaxe CLDR |
| Chargement asynchrone | Natif | Plugin | Plugin |
| Courbe d'apprentissage | Douce | Modérée | Modérée |
react-intl mise sur le standard ICU MessageFormat et propose un ensemble riche de composants Formatted. Il brille dans les projets où la qualité et la cohérence des traductions sont primordiales, mais son API peut sembler verbeuse pour des cas simples. FormatJS s'appuie sur la même philosophie et partage de nombreux concepts avec react-intl.
react-i18next privilégie la souplesse et une prise en main rapide. Son architecture de plugins permet d'étendre facilement le comportement, des chargeurs backend aux détecteurs personnalisés. Pour la plupart des projets React, en particulier ceux qui utilisent déjà i18next côté serveur, cette option offre un bon compromis entre fonctionnalités et simplicité.
Détection et changement de langue
La détection automatique repose sur plusieurs signaux consultés dans un ordre précis : le drapeau dans localStorage défini lors des sessions précédentes, l'objet navigator, puis le chemin de l'URL. Le plugin i18next-browser-languagedetector gère cette chaîne par défaut, mais vous pouvez personnaliser l'ordre ou ajouter une vérification des paramètres de requête pour les campagnes marketing.
Quelques pistes pour fiabiliser le changement de langue :
- Stocker la préférence utilisateur dans localStorage ou un cookie persistant
- Synchroniser l'URL avec un préfixe de langue pour faciliter le partage de liens
- Proposer un sélecteur visible et accessible, surtout sur les sites e-commerce
- Éviter les redirections brutales qui perturbent le référencement
Changer manuellement de langue revient généralement à appeler i18n.changeLanguage(newLang) depuis un composant sélecteur. Vous pouvez conserver le choix dans un cookie ou localStorage, et react-i18next le récupèrera lors de la visite suivante grâce au détecteur. Respecter la préférence utilisateur évite de le surprendre avec la langue par défaut du navigateur et améliore l'expérience globale.
Bonnes pratiques et optimisation
Voici quelques réflexes à adopter pour garder une base de traductions saine :
- Centraliser les clés communes dans un namespace partagé pour éviter les doublons
- Prévoir des clés par défaut pour tous les namespaces, même ceux chargés en différé
- Tester l'application en inversant la langue pour repérer les chaînes manquantes
- Mettre en place un linting avec eslint-plugin-i18next pour signaler les clés invalides
Côté performance, le chargement à la demande des namespaces réduit le poids du bundle initial. Le cache du navigateur prend ensuite le relais pour les sessions suivantes, ce qui évite de télécharger les mêmes ressources à chaque navigation. Une autre astuce consiste à regrouper les traductions statiques dans des bundles générés au moment du build, afin de bénéficier du tree shaking.
L'internationalisation ne se limite pas à la traduction des chaînes de caractères. Les formats de date, les devises, la direction du texte et les conventions culturelles varient d'une région à l'autre. Une approche holistique évite les régressions visuelles et offre une expérience cohérente, quel que soit le marché visé.
Pour mettre en pratique ces concepts sur un projet concret, vous pouvez consulter ce tutoriel qui montre comment construire une application météo avec React et l'API Weatherstack et y ajouter ensuite la couche multilingue décrite dans cet article.