Skip to main content

De complete gids voor internationalisatie in React

Van nul naar meertalig: stel i18n in je React-app in en automatiseer daarna vertalingen met AI.

1

Pakketten installeren

Je hebt drie pakketten nodig: react-i18next (de React-koppelingen), i18next (de kernbibliotheek) en eventueel i18next-browser-languagedetector voor automatische localedetectie.

react-i18next biedt React-hooks en -componenten. i18next is de kern die vertalingen laadt en interpolatie en meervoudsvormen verwerkt. De plug-in voor taaldetectie leest automatisch de taalvoorkeur van de browser.
Terminal
npm install react-i18next i18next i18next-browser-languagedetector i18next-http-backend
2

De i18n-instantie configureren

Maak een i18n-configuratiebestand dat i18next initialiseert met je standaardtaal, vertaalbronnen en plug-inketen. Importeer dit bestand bij het toegangspunt van je app voordat er een component wordt gerenderd.

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" — deze fout betekent dat je i18n.use(initReactI18next) niet hebt aangeroepen vóór i18n.init(). De aanroep .use() moet vóór .init() staan.
3

Je app in I18nextProvider verpakken

Importeer je i18n-configuratiebestand in de hoofdmap van de app en verpak je componentstructuur in I18nextProvider. Zonder deze provider retourneert useTranslation() onbewerkte sleutels in plaats van vertaalde tekst.

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>
);
Als vertalingen onbewerkte sleutels zoals "welcome" tonen in plaats van "Welcome to our app", ontbreekt meestal I18nextProvider of is het i18n-configuratiebestand niet geïmporteerd.
4

Vertaalbestanden maken

Maak één JSON-bestand per taal. Gebruik geneste sleutels om teksten per functie of pagina te ordenen. Houd je brontaal (meestal Engels) aan als de enige gezaghebbende bron.

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"
  }
}
Geef sleutels een naam op basis van wat ze beschrijven, niet waar ze staan: "cart.itemCount" is beter dan "homepageCartLabel". Sleutels moeten een nieuw UI-ontwerp kunnen doorstaan.
5

Vertalingen in componenten gebruiken

Roep useTranslation() in een component aan om de functie t() op te halen. Gebruik die voor eenvoudige teksten, geïnterpoleerde variabelen en vertalingen met JSX via de component 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" />
    }} />
  );
}
Dynamische sleutels zoals t(`error.$'{code}'`) werken tijdens runtime, maar kunnen niet statisch worden uitgelezen door tools zoals i18next-scanner. Vermeld dynamische sleutels expliciet of gebruik een aanwijzing in een opmerking als je extractietools gebruikt.
6

Meervoudsvormen en variabelen verwerken

i18next verwerkt meervoudsvormen met CLDR-regels, dus niet alleen enkelvoud en meervoud. Het Arabisch heeft 6 vormen (zero, one, two, few, many, other) en het Japans 1 (other). Definieer alle vereiste vormen in je vertaalbestanden; i18next selecteert automatisch de juiste.

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}}個のアイテム"
}
Codeer count === 1 nooit hard om het enkelvoud te detecteren. Talen zoals het Frans behandelen 0 als enkelvoud. Het Russisch, Arabisch en Pools kennen vormen die het Engels niet heeft. Laat i18next de meervoudsregels afhandelen.
7

Taalkeuze en -detectie toevoegen

Bouw een taalkiezer die i18n.changeLanguage() aanroept. Combineer die met de taaldetectie van de browser om bij het eerste bezoek automatisch de voorkeurstaal van de gebruiker te herkennen en sla diens expliciete keuze daarna op.

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>
  );
}
Als je SSR gebruikt (Next.js, Remix), kan de server een andere taal detecteren dan de client, omdat de server geen browservoorkeuren kent. Dit veroorzaakt een hydratiefout. Geef de gedetecteerde locale vanaf de server als prop of cookie door aan de client, zodat beide dezelfde taal renderen.
8

Vertalingen automatiseren

Nu je i18n-configuratie klaar is, kun je je localebestanden met AI vertalen. Vraag je AI-assistent in je IDE om het bronbestand te vertalen of gebruik de i18n Agent CLI in je CI/CD-pipeline.

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
Vertaal stapsgewijs: vertaal alleen de wijzigingen wanneer je nieuwe sleutels aan het bronbestand toevoegt, in plaats van alle bestanden opnieuw te genereren. Zo blijven door mensen beoordeelde vertalingen behouden.

Kwaliteitscontrole van vertalingen automatiseren

Vind ontbrekende sleutels en kapotte plaatsaanduidingen vóór de release met i18n-validate. Test je gebruikersinterface met testvertalingen uit i18n-pseudo voordat de echte vertalingen klaar zijn.

Veelvoorkomende valkuilen

Vertalingen tonen onbewerkte sleutels

Mogelijke oorzaken: I18nextProvider ontbreekt, de i18n-configuratie is niet in de hoofdmap van de app geïmporteerd, de namespace is niet geladen of vertalingen worden nog asynchroon geladen. Controleer de browserconsole met debug: true voor aanwijzingen.

Suspense-fout zonder fallback

"A component suspended while responding to synchronous input" — voeg een '&lt;Suspense&gt;'-grens rond je app toe of stel useSuspense: false in de initialisatieconfiguratie van i18next in.

SSR-hydratiefout

De server rendert in de ene locale en de client hydrateert in een andere. Zorg dat beide dezelfde localebron gebruiken: geef die vanaf de server door als prop en vertrouw niet alleen op browserdetectie.

Geen automatische aanvulling voor vertaalsleutels

Breid de i18next-module uit met je brontype: declare module 'i18next' '{ interface CustomTypeOptions { resources: typeof resources } }'. Zo krijg je typeveilige aanroepen van t() met automatische aanvulling.

Aanbevolen bestandsstructuur

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

Probeer i18n Agent nu

Zet je vertaalbestand hier neer

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

of klik om een bestand te selecteren

Doeltalen

Geen registratie nodigDirecte prijsindicatie

Veelgestelde vragen