Posez votre question et obtenez un résumé du document en referencant cette page et le Provider AI de votre choix
Le contenu de cette page a été traduit à l'aide d'une IA.
Voir la dernière version du contenu original en anglaisSi vous avez une idée d’amélioration pour améliorer cette documentation, n’hésitez pas à contribuer en submitant une pull request sur GitHub.
Lien GitHub de la documentationCopier le Markdown du doc dans le presse-papiers
Comment choisir la bonne bibliothèque i18n pour React
React ne fournit aucune primitive i18n. La bibliothèque que vous choisissez dès le premier jour détermine la manière dont les traductions sont stockées, comment elles arrivent dans le bundle, et la charge de maintenance qui vous incombera pour les années à venir. La plupart des équipes choisissent par popularité, puis découvrent les compromis une fois arrivées à 2 000 clés.
Ce guide adopte l'approche inverse : répondez d'abord à quelques questions sur votre projet, puis associez ces réponses aux bibliothèques correspondantes. Il se concentre sur React pur (Vite, React Router, TanStack Start). Next.js a ses propres contraintes, détaillées dans le comparatif Next.js.

Table of Contents
Six questions à se poser avant de comparer les bibliothèques
Un tableau de fonctionnalités est inutile si vous ne savez pas quelles lignes comptent pour vous. Commencez par répondre à celles-ci.
- Comment l'application est-elle rendue ? SPA uniquement, SSR avec hydratation, ou React Server Components. Les hooks basés sur le contexte fonctionnent partout dans une SPA. Avec RSC, un hook impose
"use client"sur chaque composant qui affiche du texte, vous aurez donc également besoin d'une API côté serveur. - Qui rédige les traductions ? Les développeurs, une équipe interne utilisant un TMS, une agence livrant des fichiers ICU, ou un pipeline IA. Cela dicte le format de catalogue bien plus que n'importe quel détail d'API.
- Combien de locales et de pages ? Deux locales et cinq pages peuvent se permettre de tout inclure dans le bundle. Dix locales et cinquante routes ne le peuvent pas, et la stratégie de chargement devient alors le coût principal.
- Avez-vous besoin du typage sur les clés ? Une faute de frappe dans
t("checkout.totl")compile dans toutes les bibliothèques basées sur des clés, à moins de configurer le typage vous-même. Décidez si cela est acceptable. - Que contient la chaîne de caractères ? Du texte brut, des pluriels, ou des phrases avec un composant
<Link>au milieu. Le contenu riche est le point où la plupart des API deviennent peu pratiques. - Combien de temps vivra le projet ? Un prototype de trois mois et un produit de cinq ans ne nécessitent pas la même quantité d'outillage de build.
Notez vos réponses. Tout ce qui suit y fait référence.
Le paysage en une image
Quinze ans d'i18n JavaScript se résument en quatre vagues architecturales, et les bibliothèques React que vous allez comparer sont issues de vagues différentes.

Catalogues JSON chargés en mémoire, résolution de t("a.b") au runtime, syntaxe ICU ou personnalisée analysée dans le navigateur. Plus grands écosystèmes, runtimes les plus lourds, typage optionnel.
Messages extraits au build, compilés en catalogues compacts, arguments typés. Une étape de build supplémentaire (extract, compile) en échange de bundles plus légers.
Conçus autour du SSR et des Server Components. Rendu sur le serveur, hydratation uniquement de ce dont le client a besoin. Toujours basés sur des clés et centralisés.
Le contenu est compilé en fonctions optimisées pour le tree-shaking ou en dictionnaires par composant. Les types sont générés, les traductions manquantes font échouer le build, et la traduction par IA s'exécute depuis la CLI.
L'histoire de l'i18n JavaScript détaille la manière dont chaque vague a répondu aux problèmes de la précédente.
La décision la plus importante : où vit le contenu et quand il se charge
Toutes les bibliothèques React i18n partagent la même structure : un store, un provider, un hook. Tout ce que le provider reçoit se retrouve dans le bundle client ou dans le payload d'hydratation. Les deux choix structurels sont donc :
- Contenu centralisé ou scopé. Un seul
en.jsonpour toute l'application, ou une déclaration par composant (ou par namespace). - Import statique ou dynamique. Tout est packagé au démarrage, ou bien la locale active et la route sont récupérées à la demande.
Le graphique ci-dessous estime le payload pour une application théorique de 1 à 10 pages, traduite en 1 à 10 locales, avec environ 30 Ko de texte par page.

Le contenu centralisé avec imports statiques augmente sur les deux axes : 10 pages multipliées par 10 locales représentent 300 Ko de texte sur chaque page. Les imports dynamiques suppriment l'axe des locales. Le scoping supprime l'axe des pages. Seule la combinaison des deux permet de maintenir un payload constant.
Ce n'est pas une propriété intrinsèque de la bibliothèque, mais une question de discipline. react-i18next peut être scopé avec des namespaces et des backends asynchrones. use-intl peut être découpé par route. Mais rien ne l'impose, et un simple <Button> partagé appelant t("common:cta") transforme discrètement common en une dépendance de chaque route. Le benchmark mesure cela sous les termes de « fuite depuis d'autres routes » et « fuite depuis d'autres locales », et c'est de là que provient la majeure partie des écarts entre les bibliothèques.
Si votre réponse à la question 3 était « beaucoup de locales, beaucoup de pages », accordez plus d'importance à cette section qu'à toute préférence d'API. L'article i18n par composant vs centralisée approfondit l'impact sur la maintenance de ce même choix.
Les candidats
La taille des bibliothèques provient du benchmark TanStack Start : provider et hook dans un composant vide, après bundling, tree-shaking et minification, pour 10 pages et 10 locales. Le contenu est mesuré séparément.
Ouvrir le tableau dans une fenêtre modale pour voir tout le contenu clairement
| Bibliothèque | Vague | Modèle de contenu | Typage des clés | Format de message | Taille de la bibliothèque |
|---|---|---|---|---|---|
react-i18next | Runtime | JSON centralisé, namespaces | Optionnel (CustomTypeOptions) | i18next (pluriels par suffixe) | ~18.4 ko |
react-intl (FormatJS) | Runtime | JSON centralisé, ICU | Optionnel (extraction + union) | ICU | ~15.3 ko |
use-intl | Server-first | JSON centralisé, ICU | Optionnel (declaration merging) | ICU | ~14.1 ko |
@tolgee/react | Runtime | Centralisé, édition in-context | Non | ICU | ~11.1 ko |
| Lingui | Macro | Texte source dans le code, catalogues compilés | Bon, via le compilateur | ICU via macros | Légère |
| Paraglide | Compilateur | Projet inlang, fonctions générées | Généré | Propriétaire | Proche de zéro |
| Intlayer | Compilateur | .content.ts par composant | Généré, actif par défaut | Helpers (plural, enu) | Référence |
Les chiffres correspondent à un instantané basé sur les versions du benchmark et évoluent au fil des publications. Exécutez le benchmark sur votre propre application avant de vous décider uniquement sur la taille.
Deux éléments que le tableau ne montre pas. Paraglide n'embarque presque aucune bibliothèque car il génère du code directement dans votre codebase, ce qui implique une étape de régénération avant chaque commit et de potentiels conflits de fusion sur les fichiers générés. De son côté, Intlayer nécessite un plugin de bundler (vite-intlayer ou équivalent), et ne peut donc pas fonctionner dans une configuration sans étape de build.
Associer vos réponses à une bibliothèque
Choisissez la solution la plus simple qui fonctionne sans surinvestir. react-i18next avec un seul fichier JSON par locale convient très bien, et dix ans de réponses sur Stack Overflow vous feront gagner du temps. Ignorez les namespaces tant que vous n'en avez pas besoin. Si le prototype devient un produit, prévoyez une migration vers un contenu scopé ; l'adaptateur de compatibilité react-i18next permet de le faire de manière incrémentale.
Le format de votre catalogue est imposé. react-intl gère nativement ICU et l'outillage d'extraction FormatJS est conçu pour ce pipeline. use-intl lit également ICU. react-i18next nécessite le plugin ICU et ses propres clés de pluriel dans le cas contraire. Le support ICU d'Intlayer est encore partiel, donc si vous recevez des chaînes ICU aujourd'hui, considérez cela comme bloquant jusqu'à son intégration complète.
Privilégiez le contenu scopé et le chargement dynamique par défaut, plutôt que par simple convention. Lingui et Paraglide y parviennent grâce à la compilation. Intlayer y parvient grâce aux déclarations par composant, et le compilateur n'embarque que ce qu'une route affiche. Avec react-i18next ou use-intl, planifiez la stratégie de namespaces et de lazy loading dès le premier jour et faites-la respecter en revue de code, car l'outillage ne le fera pas à votre place.
Toutes les bibliothèques basées sur des clés peuvent être typées, mais presque aucune ne l'est par défaut. Si vous ne souhaitez pas maintenir du declaration merging devant survivre aux namespaces chargés paresseusement, choisissez une bibliothèque où les types sont générés à partir du contenu : Lingui, Paraglide ou Intlayer. L'article sur la détection des traductions manquantes compare ce que chacune détecte au moment du build.
Les nœuds riches sont l'endroit où le modèle de t() renvoyant une simple chaîne de caractères montre ses limites. react-i18next et Lingui utilisent <Trans>, react-intl utilise des balises de texte riche, des approches toutes plus verbeuses que pour de simples chaînes. Les nœuds de contenu d'Intlayer acceptent directement du JSX, du markdown et des objets imbriqués, ce qui est bien plus adapté lorsque le contenu dépasse de simples libellés d'interface.
Un JSON centralisé n'est alors plus obligatoire, puisqu'il n'y a pas de TMS externe vers lequel importer les données. Un contenu colocalisé associé à une CLI qui complète les locales manquantes est la voie la plus directe. La commande fill d'Intlayer s'exécute avec votre propre clé d'API (OpenAI, Anthropic, Mistral, Gemini) et ne traduit que ce qui a été modifié. Paraglide et Tolgee proposent des équivalents hébergés avec leurs propres forfaits.
Le contexte React ne traverse pas la frontière client/serveur. Les bibliothèques basées uniquement sur un hook client (react-i18next, react-intl) nécessiteront une API serveur parallèle dès que vous adopterez les RSC. use-intl (via next-intl) et Intlayer (via next-intlayer) intègrent déjà cette distinction. Consultez l'article sur l'i18n avec Next.js avant d'uniformiser un pattern.
Les limites de chaque bibliothèque
Des limites en toute transparence, car chaque option en présente.
react-i18next: la plus lourde de l'ensemble, format de pluriel propriétaire, typage à configurer et maintenir soi-même, accumulation silencieuse de clés mortes.react-intl: DX verbeuse (useIntl()puisformatMessage({ id })), instance globale liée à de nombreux nœuds.use-intl: simple pour débuter, complexe à optimiser. Les namespaces, le chargement dynamique et le typage combinés ralentissent nettement le développement.Lingui: étape de build supplémentaire (extract/compile), plusieurs syntaxes concurrentes (t(), template taggé,i18n.t(),<Trans>) qui créent de la confusion tant pour les humains que pour les assistants IA.Paraglide: fichiers générés dans la codebase, le tree-shaking n'a pas été effectif lors du benchmark React, et la locale est lue depuis le storage sur chaque nœud plutôt qu'à partir d'un store.Tolgee: aucun typage des clés, intégration plus difficile, l'édition in-context est son principal atout commercial.Intlayer: plugin de build obligatoire, écosystème plus restreint, support partiel d'ICU, contenu réparti dans la codebase par conception nécessitant un outillage pour exporter un JSON unique à un traducteur.gt-react,lingo.dev: non recommandés dans le benchmark : erreurs de quota lors du build, verrouillage propriétaire (vendor lock-in), et problèmes de réactivité nécessitant de forcer le re-rendu du provider.
À quoi ressemble chaque option en code
Le même composant, un récapitulatif de panier avec un titre et un pluriel, écrit avec chaque candidat. L'aspect intéressant n'est pas le composant lui-même, mais l'endroit où réside le contenu et les informations dont dispose le vérificateur de types.
Copier le code dans le presse-papiers
Copier le code dans le presse-papiers
Les pluriels sont des clés suffixées résolues via Intl.PluralRules. t a pour signature (key: string) => string sauf si vous déclarez CustomTypeOptions, ce qui fait que t("titel") compile sans erreur.
Copier le code dans le presse-papiers
Copier le code dans le presse-papiers
ICU de bout en bout, ce que la plupart des plateformes TMS exportent. Les types sur id proviennent de l'étape d'extraction formatjs et d'une union générée, et non d'un comportement par défaut.
Copier le code dans le presse-papiers
Copier le code dans le presse-papiers
Même structure que next-intl sans les liaisons spécifiques à Next.js. Les clés sont typées une fois que vous étendez AppConfig avec le type des messages ; la séparation des namespaces reste à votre charge.
Copier le code dans le presse-papiers
Copier le code dans le presse-papiers
La langue source réside dans le composant ; les autres locales se trouvent dans des fichiers .po sous des identifiants hachés après l'exécution de lingui extract. Oublier extract ou compile bascule silencieusement vers l'anglais.
Copier le code dans le presse-papiers
Copier le code dans le presse-papiers
Chaque message est une fonction générée et typée, de sorte qu'une clé manquante se traduit par une erreur d'import. Le dossier paraglide/ est généré dans votre dépôt et régénéré à chaque modification.
Copier le code dans le presse-papiers
Copier le code dans le presse-papiers
Toutes les locales dans un seul fichier à côté du composant. Les types sont générés au build, ce qui permet à title d'être autocomplété et à une faute de frappe de faire échouer tsc sans recourir au declaration merging. Supprimer le dossier supprime également les chaînes associées.
Vous utilisez déjà react-i18next, react-intl ou Lingui ? Les adaptateurs de compatibilité (react-i18next, react-intl, Lingui) créent des alias d'imports au niveau du bundler pour que l'API existante continue de fonctionner pendant votre migration composant par composant. Le guide de migration couvre le reste.
Avant de faire votre choix
Un tableau de fonctionnalités indique ce qu'une bibliothèque propose aujourd'hui. Les points suivants expliquent ce que sera son utilisation au quotidien.
Vérifiez l'activité du dépôt.
Commits, temps de réponse sur les issues et date de la dernière version mineure. Une architecture solide sans mainteneur est une future migration programmée.
Ne choisissez pas selon les téléchargements npm.
La bibliothèque la plus installée est celle qui est sortie en premier, pas nécessairement celle qui convient à une codebase React en 2026. Les téléchargements mesurent l'antériorité, pas la pertinence.

Demandez-vous qui finance le mainteneur et ce qu'il vend.
i18next est soutenu par Locize. next-intl / use-intl, vue-i18n, svelte-i18n et Lingui sont soutenus par Crowdin. Tolgee, Paraglide (inlang) et Intlayer exploitent chacun leur propre plateforme. Un fournisseur dont le modèle économique repose sur l'hébergement des traductions a peu d'intérêt à rendre la traduction gratuite au sein de votre chaîne d'outils. Intlayer est le seul du groupe à intégrer la traduction par IA via la CLI avec votre propre clé d'API, ainsi qu'un CMS auto-hébergeable.
Est-elle prête pour les agents IA ?
Les agents rencontrent encore des difficultés avec l'i18n : ils oublient des locales, inventent des clés et mélangent les syntaxes de messages. La bibliothèque fournit-elle des Agent Skills ou un serveur MCP afin que l'agent puisse lister, compléter et tester le contenu ? Et le chargement du contenu est-il optimisé par défaut, ou bien quelqu'un doit-il auditer les namespaces et les imports asynchrones chaque trimestre ?
Sûreté de typage prête à l'emploi.
Pas simplement « peut être typé avec une configuration supplémentaire », mais « une clé invalide fait échouer tsc dès l'installation initiale ». Vérifiez le comportement en cas de clé inexistante et lorsqu'une locale omet une traduction.
Détection du contenu inutilisé.
Les catalogues ne font que grossir. Le build d'Intlayer purge les champs inutilisés et les consigne dans les logs (build.purge). Paraglide y parvient par son architecture, puisqu'une fonction de message non appelée est éliminée par tree-shaking. Toutes les autres solutions vous laissent gérer ce nettoyage manuellement.
Expérience développeur.
Temps de configuration avant la première chaîne traduite, présence d'un LSP ou d'une extension VS Code affichant la traduction au survol et permettant d'accéder à la déclaration, une CLI pour compléter (fill), tester et publier (push), et un moyen pour les non-développeurs d'éditer le contenu (éditeur visuel ou CMS) sans passer par une pull request.
Foire aux questions
Oui pour la plupart des équipes. Il dispose du plus vaste écosystème et du plus grand nombre de ressources en ligne. Ses inconvénients sont réels mais prévisibles : le runtime le plus lourd, un format de pluriel propriétaire, ainsi qu'une sûreté de typage et un scoping que vous devez configurer et maintenir vous-même.
Uniquement si la taille du bundle, les types générés ou les vérifications de clés manquantes à la compilation font partie de vos exigences. Pour une petite application avec deux locales, une bibliothèque au runtime est plus simple. L'article compilateur vs i18n déclarative détaille les avantages des compilateurs et leurs pièges potentiels.
Partiellement. Les bibliothèques basées sur des clés partagent une structure suffisamment proche pour qu'un adaptateur de compatibilité puisse faire correspondre une API à une autre, ce qui correspond au fonctionnement des adaptateurs Intlayer. Les formats de messages (ICU vs i18next vs helpers) ne se convertissent pas automatiquement, les pluriels et l'interpolation constituent donc la partie que vous devrez adapter.
Indirectement. Ce que voient les moteurs de recherche dépend du routage, des balises hreflang, de <html lang> et de la présence du texte dans le HTML rendu côté serveur. Certaines bibliothèques fournissent des helpers dédiés, la plupart vous laissent gérer cela. Consultez le guide hreflang.
Pour aller plus loin
- Benchmark des bibliothèques i18n : bundle size, fuites et temps de basculement de locale et le rapport TanStack Start
- React i18n : fonctionnement du modèle provider et ses coûts
- react-i18next vs react-intl vs Intlayer, fonctionnalité par fonctionnalité
- next-i18next vs next-intl vs Intlayer
- L'histoire de l'i18n JavaScript
- Compilateur vs i18n déclarative
- i18n par composant vs centralisée
- Comment fonctionne l'optimisation de bundle au moment du build
- Configurer l'i18n dans une application Vite + React
- Même guide pour Vue, Svelte et Solid
Commentaires
Aucun commentaire pour le moment. Soyez le premier à partager vos pensées.
