Skip to main content

Le guide complet de l'internationalisation avec React

De zéro au multilingue : configurez l'i18n dans votre application React, puis automatisez les traductions avec l'IA.

1

Installer les packages

Vous avez besoin de trois packages : react-i18next (les liaisons React), i18next (la bibliothèque principale) et, en option, i18next-browser-languagedetector pour la détection automatique de la langue.

react-i18next fournit des hooks et des composants React. i18next est le moteur principal qui gère le chargement des traductions, l'interpolation et la pluralisation. Le plugin de détection de langue lit automatiquement la préférence de langue du navigateur.
Terminal
npm install react-i18next i18next i18next-browser-languagedetector i18next-http-backend
2

Configurer l'instance i18n

Créez un fichier de configuration i18n qui initialise i18next avec votre langue par défaut, vos ressources de traduction et votre chaîne de plugins. Ce fichier doit être importé au point d'entrée de votre application avant le rendu de tout composant.

src/i18n.ts
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import Backend from 'i18next-http-backend';

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)  // Must come before .init()
  .init({
    fallbackLng: 'en',
    debug: process.env.NODE_ENV === 'development',
    interpolation: {
      escapeValue: false,  // React already escapes
    },
    backend: {
      loadPath: '/locales/{{lng}}/{{ns}}.json',
    },
  });

export default i18n;
« You will need to pass in an i18next instance by using initReactI18next » — cette erreur signifie que vous avez oublié d'appeler i18n.use(initReactI18next) avant i18n.init(). L'appel à .use() doit précéder celui à .init().
3

Encapsulez votre application avec I18nextProvider

Importez votre fichier de configuration i18n à la racine de l'application et encapsulez votre arborescence de composants avec I18nextProvider. Sans cela, useTranslation() renvoie les clés brutes au lieu du texte traduit.

src/main.tsx
import React, { Suspense } from 'react';
import ReactDOM from 'react-dom/client';
import { I18nextProvider } from 'react-i18next';
import i18n from './i18n';  // Import your config
import App from './App';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <Suspense fallback={<div>Loading...</div>}>
      <I18nextProvider i18n={i18n}>
        <App />
      </I18nextProvider>
    </Suspense>
  </React.StrictMode>
);
Si les traductions affichent des clés brutes comme « welcome » au lieu de « Welcome to our app », la cause la plus fréquente est l'absence d'I18nextProvider ou l'oubli de l'importation du fichier de configuration i18n.
4

Créer des fichiers de traduction

Créez un fichier JSON par langue. Utilisez des clés imbriquées pour organiser les chaînes par fonctionnalité ou par page. Conservez votre langue source (généralement l'anglais) comme source de référence unique.

public/locales/en/translation.json
// public/locales/en/translation.json
{
  "nav": {
    "home": "Home",
    "about": "About",
    "settings": "Settings"
  },
  "greeting": "Hello, {{name}}!",
  "cart": {
    "itemCount_one": "{{count}} item",
    "itemCount_other": "{{count}} items"
  }
}

// public/locales/de/translation.json
{
  "nav": {
    "home": "Startseite",
    "about": "Über uns",
    "settings": "Einstellungen"
  },
  "greeting": "Hallo, {{name}}!",
  "cart": {
    "itemCount_one": "{{count}} Artikel",
    "itemCount_other": "{{count}} Artikel"
  }
}
Nommez les clés en fonction de ce qu'elles décrivent, et non de l'endroit où elles apparaissent : « cart.itemCount » est préférable à « homepageCartLabel ». Les clés doivent survivre aux refontes de l'interface.
5

Utiliser les traductions dans les composants

Appelez useTranslation() dans n'importe quel composant pour obtenir la fonction t(). Utilisez-la pour les chaînes simples, les variables interpolées et les traductions intégrées en JSX avec le composant Trans.

Greeting.tsx
import { useTranslation } from 'react-i18next';

function Greeting({ userName }: { userName: string }) {
  const { t } = useTranslation();

  return (
    <div>
      <h1>{t('greeting', { name: userName })}</h1>
      <nav>
        <a href="/">{t('nav.home')}</a>
        <a href="/about">{t('nav.about')}</a>
      </nav>
    </div>
  );
}
Trans component for JSX
import { Trans, useTranslation } from 'react-i18next';

// For JSX inside translations:
// "terms": "By signing up, you agree to our <link>Terms</link>."

function SignUp() {
  const { t } = useTranslation();
  return (
    <Trans i18nKey="terms" components={{
      link: <a href="/terms" className="underline" />
    }} />
  );
}
Les clés dynamiques comme t(`error.$'{code}'`) fonctionnent à l'exécution, mais ne peuvent pas être extraites statiquement par des outils comme i18next-scanner. Si vous utilisez des outils d'extraction, listez explicitement les clés dynamiques ou utilisez une indication en commentaire.
6

Gérer les pluriels et les variables

i18next gère les pluriels à l'aide des règles CLDR — pas seulement le singulier et le pluriel. L'arabe compte 6 formes (zero, one, two, few, many, other). Le japonais n'en a qu'une (other). Définissez toutes les formes requises dans vos fichiers de traduction, et i18next sélectionne automatiquement la bonne.

Plural forms by language
// English: 2 forms (one, other)
{
  "itemCount_one": "{{count}} item",
  "itemCount_other": "{{count}} items"
}

// Arabic: 6 forms (zero, one, two, few, many, other)
{
  "itemCount_zero": "لا عناصر",
  "itemCount_one": "عنصر واحد",
  "itemCount_two": "عنصران",
  "itemCount_few": "{{count}} عناصر",
  "itemCount_many": "{{count}} عنصرًا",
  "itemCount_other": "{{count}} عنصر"
}

// Japanese: 1 form (other)
{
  "itemCount_other": "{{count}}個のアイテム"
}
Ne codez jamais en dur count === 1 pour détecter le singulier. Des langues comme le français traitent 0 comme un singulier. Le russe, l'arabe et le polonais possèdent des formes que l'anglais n'a pas. Laissez i18next gérer les règles de pluriel.
7

Ajouter le changement et la détection de langue

Créez un sélecteur de langue qui appelle i18n.changeLanguage(). Combinez-le avec le détecteur de langue du navigateur pour détecter automatiquement la langue préférée de l'utilisateur lors de la première visite, puis conservez son choix explicite.

LanguageSwitcher.tsx
import { useTranslation } from 'react-i18next';

const LANGUAGES = [
  { code: 'en', label: 'English' },
  { code: 'de', label: 'Deutsch' },
  { code: 'ja', label: '日本語' },
  { code: 'es', label: 'Español' },
];

function LanguageSwitcher() {
  const { i18n } = useTranslation();

  return (
    <select
      value={i18n.language}
      onChange={(e) => i18n.changeLanguage(e.target.value)}
    >
      {LANGUAGES.map(({ code, label }) => (
        <option key={code} value={code}>{label}</option>
      ))}
    </select>
  );
}
Si vous utilisez le SSR (Next.js, Remix), le serveur peut détecter une langue différente de celle du client (le serveur n'a pas accès aux préférences du navigateur). Cela provoque une incohérence d'hydratation. Solution : transmettez la locale détectée du serveur au client sous forme de prop ou de cookie, afin que les deux rendent la même langue.
8

Automatiser les traductions

Une fois votre configuration i18n terminée, traduisez vos fichiers de locale à l'aide de l'IA. Dans votre IDE, demandez à votre assistant IA de traduire votre fichier source, ou utilisez l'outil CLI i18n Agent dans votre pipeline CI/CD.

Terminal
# In your IDE, ask your AI assistant:
> Translate public/locales/en/translation.json to German, Japanese, and Spanish

✓ de/translation.json created (1.2s)
✓ ja/translation.json created (1.5s)
✓ es/translation.json created (1.1s)

# Or use the CLI in CI/CD:
npx i18n-agent translate public/locales/en/translation.json --lang de,ja,es
Traduisez de façon incrémentale : lorsque vous ajoutez de nouvelles clés à votre fichier source, ne traduisez que les différences plutôt que de régénérer tous les fichiers. Cela préserve les traductions déjà relues par un humain.

Automatiser la qualité des traductions

Détectez les clés manquantes et les espaces réservés cassés avant leur mise en production avec i18n-validate. Testez votre interface avec de fausses traductions grâce à i18n-pseudo avant l'arrivée des traductions réelles.

Pièges courants

Les traductions affichent des clés brutes

Causes : I18nextProvider manquant, configuration i18n non importée à la racine de l'application, espace de noms non chargé, ou traductions encore en cours de chargement asynchrone. Consultez la console du navigateur avec debug: true pour obtenir des indices.

Erreur Suspense sans repli

« A component suspended while responding to synchronous input » — ajoutez une limite '&lt;Suspense&gt;' autour de votre application, ou définissez useSuspense: false dans la configuration d'initialisation d'i18next.

Incohérence d'hydratation SSR

Le serveur effectue le rendu dans une locale, le client hydrate dans une autre. Assurez-vous que les deux utilisent la même source de locale — transmettez-la sous forme de prop depuis le serveur, ne vous fiez pas uniquement à la détection du navigateur.

Pas d'autocomplétion pour les clés de traduction

Augmentez le module i18next avec votre type de ressource : declare module 'i18next' '{ interface CustomTypeOptions { resources: typeof resources } }'. Cela vous donne des appels t() typés en toute sécurité, avec autocomplétion.

Structure de fichiers recommandée

Project Structure
my-react-app/
├── public/
│   └── locales/
│       ├── en/
│       │   ├── translation.json    # Default namespace
│       │   ├── common.json         # Shared strings
│       │   └── dashboard.json      # Feature namespace
│       ├── de/
│       │   ├── translation.json
│       │   ├── common.json
│       │   └── dashboard.json
│       └── ja/
│           └── ...
├── src/
│   ├── i18n.ts                     # i18n configuration
│   ├── main.tsx                    # App entry with Provider
│   ├── App.tsx
│   └── components/
│       └── LanguageSwitcher.tsx
└── package.json

Essayez i18n Agent maintenant

Déposez votre fichier de traduction ici

JSON, YAML, PO, XML, CSV, Markdown, Properties

ou cliquez pour parcourir

Langues cibles

Aucune inscription requiseEstimation instantanée

Questions fréquentes