Einführung#

Eine React-App für ein internationales Publikum? Dieser Leitfaden führt durch die Internationalisierung (i18n) von der Einrichtung bis zum Deploy — mit react-i18next, der verbreitetsten i18n-Bibliothek für React.

Voraussetzungen#

  • React ab Version 18
  • npm oder yarn
  • Grundkenntnisse in React

Schritt 1: Pakete installieren#

bash
npm install i18next react-i18next i18next-http-backend i18next-browser-languagedetector
PaketZweck
i18nextder Kern
react-i18nextdie React-Anbindung
i18next-http-backendlädt Übersetzungen aus Dateien
i18next-browser-languagedetectorerkennt die Sprache des Nutzers

Schritt 2: Übersetzungsdateien anlegen#

Struktur für die Übersetzungen:

text
public/
  locales/
    en/
      translation.json
    de/
      translation.json
    es/
      translation.json

public/locales/en/translation.json:

json
{
  "welcome": "Welcome to our app",
  "nav": {
    "home": "Home",
    "about": "About",
    "contact": "Contact"
  },
  "buttons": {
    "submit": "Submit",
    "cancel": "Cancel",
    "save": "Save Changes"
  }
}

public/locales/de/translation.json:

json
{
  "welcome": "Willkommen in unserer App",
  "nav": {
    "home": "Startseite",
    "about": "Über uns",
    "contact": "Kontakt"
  },
  "buttons": {
    "submit": "Absenden",
    "cancel": "Abbrechen",
    "save": "Änderungen speichern"
  }
}

Schritt 3: i18next konfigurieren#

src/i18n.js anlegen:

javascript
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: 'en',
    debug: process.env.NODE_ENV === 'development',

    interpolation: {
      escapeValue: false, // React maskiert bereits selbst
    },

    backend: {
      loadPath: '/locales/{{lng}}/{{ns}}.json',
    },
  });

export default i18n;

Schritt 4: In der App einbinden#

src/index.js:

javascript
import React, { Suspense } from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import './i18n'; // i18n-Konfiguration laden

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <Suspense fallback={<div>Loading...</div>}>
      <App />
    </Suspense>
  </React.StrictMode>
);

Schritt 5: Übersetzungen in Komponenten nutzen#

Der Hook useTranslation#

jsx
import { useTranslation } from 'react-i18next';

function HomePage() {
  const { t } = useTranslation();

  return (
    <div>
      <h1>{t('welcome')}</h1>
      <nav>
        <a href="/">{t('nav.home')}</a>
        <a href="/about">{t('nav.about')}</a>
        <a href="/contact">{t('nav.contact')}</a>
      </nav>
      <button>{t('buttons.submit')}</button>
    </div>
  );
}

Die Komponente Trans#

Für Übersetzungen, in denen JSX steckt:

jsx
import { Trans } from 'react-i18next';

function WelcomeMessage({ name }) {
  return (
    <Trans i18nKey="greeting" values={{ name }}>
      Hello <strong>{{ name }}</strong>, welcome back!
    </Trans>
  );
}

Übersetzungsdatei:

json
{
  "greeting": "Hello <1>{{name}}</1>, welcome back!"
}

Schritt 6: Sprachumschalter#

jsx
import { useTranslation } from 'react-i18next';

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

  const languages = [
    { code: 'en', name: 'English' },
    { code: 'de', name: 'Deutsch' },
    { code: 'es', name: 'Español' },
  ];

  return (
    <select
      value={i18n.language}
      onChange={(e) => i18n.changeLanguage(e.target.value)}
    >
      {languages.map((lang) => (
        <option key={lang.code} value={lang.code}>
          {lang.name}
        </option>
      ))}
    </select>
  );
}

Schritt 7: Pluralformen#

Übersetzungsdatei:

json
{
  "items_count": "{{count}} item",
  "items_count_plural": "{{count}} items"
}

Komponente:

jsx
function CartCount({ count }) {
  const { t } = useTranslation();
  return <span>{t('items_count', { count })}</span>;
}

i18next wählt die Pluralform anhand von count selbst — auch für Sprachen mit mehr als zwei Formen.

Schritt 8: Platzhalter#

Übersetzungsdatei:

json
{
  "greeting": "Hello, {{name}}!",
  "order_status": "Your order #{{orderId}} is {{status}}"
}

Komponente:

jsx
function Greeting({ user, order }) {
  const { t } = useTranslation();

  return (
    <div>
      <h1>{t('greeting', { name: user.name })}</h1>
      <p>{t('order_status', {
        orderId: order.id,
        status: order.status
      })}</p>
    </div>
  );
}

Best Practices#

1. Schlüssel ordnen#

Verschachtelte Objekte statt einer flachen Liste:

json
{
  "pages": {
    "home": {
      "title": "Welcome",
      "description": "..."
    },
    "checkout": {
      "title": "Checkout",
      "steps": {
        "shipping": "Shipping",
        "payment": "Payment"
      }
    }
  }
}

2. Strings früh auslagern#

Nichts fest verdrahten, von Anfang an übersetzen:

jsx
// Schlecht
<button>Submit</button>

// Gut
<button>{t('buttons.submit')}</button>

3. Namespaces bei großen Apps#

Übersetzungen auf mehrere Dateien aufteilen:

javascript
// i18n.js
i18n.init({
  ns: ['common', 'home', 'checkout'],
  defaultNS: 'common',
});
jsx
// in der Komponente
const { t } = useTranslation('checkout');

4. Ladezustand abfangen#

jsx
function App() {
  const { t, ready } = useTranslation();

  if (!ready) return <LoadingSpinner />;

  return <div>{t('welcome')}</div>;
}

Und dann: die Übersetzungen#

Die Einrichtung ist der einfache Teil. Danach steht die Frage, wer die Sprachdateien füllt — und vor allem, wer sie beim nächsten Release wieder füllt.

  1. en/translation.json exportieren
  2. In shipglobal.dev laden
  3. Zielsprachen wählen
  4. Analyse lesen: sie sagt vor dem Lauf, welche Schlüssel neu sind — beim typischen Update sind das wenige Prozent
  5. Übersetzte JSON-Dateien herunterladen
  6. Nach public/locales/{lang}/ legen und ausliefern

Der zweite Durchlauf ist der eigentliche Punkt: Verschachtelung und Platzhalter bleiben erhalten, und bereits übersetzte Schlüssel kommen aus dem Gedächtnis statt erneut aus dem Modell.

Fazit#

Eine React-App mit react-i18next zu internationalisieren ist überschaubar:

  1. Pakete installieren
  2. Übersetzungsdateien anlegen
  3. i18next konfigurieren
  4. useTranslation verwenden
  5. Sprachumschalter ergänzen

Fang mit den Sprachen an, die dein Traffic bereits zeigt, und erweitere danach. Sauber aufgesetzt dauert eine weitere Sprache Minuten, nicht Tage.