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#
npm install i18next react-i18next i18next-http-backend i18next-browser-languagedetector
| Paket | Zweck |
|---|---|
| i18next | der Kern |
| react-i18next | die React-Anbindung |
| i18next-http-backend | lädt Übersetzungen aus Dateien |
| i18next-browser-languagedetector | erkennt die Sprache des Nutzers |
Schritt 2: Übersetzungsdateien anlegen#
Struktur für die Übersetzungen:
public/
locales/
en/
translation.json
de/
translation.json
es/
translation.json
public/locales/en/translation.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:
{
"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:
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:
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#
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:
import { Trans } from 'react-i18next';
function WelcomeMessage({ name }) {
return (
<Trans i18nKey="greeting" values={{ name }}>
Hello <strong>{{ name }}</strong>, welcome back!
</Trans>
);
}
Übersetzungsdatei:
{
"greeting": "Hello <1>{{name}}</1>, welcome back!"
}
Schritt 6: Sprachumschalter#
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:
{
"items_count": "{{count}} item",
"items_count_plural": "{{count}} items"
}
Komponente:
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:
{
"greeting": "Hello, {{name}}!",
"order_status": "Your order #{{orderId}} is {{status}}"
}
Komponente:
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:
{
"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:
// Schlecht
<button>Submit</button>
// Gut
<button>{t('buttons.submit')}</button>
3. Namespaces bei großen Apps#
Übersetzungen auf mehrere Dateien aufteilen:
// i18n.js
i18n.init({
ns: ['common', 'home', 'checkout'],
defaultNS: 'common',
});
// in der Komponente
const { t } = useTranslation('checkout');
4. Ladezustand abfangen#
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.
en/translation.jsonexportieren- In shipglobal.dev laden
- Zielsprachen wählen
- Analyse lesen: sie sagt vor dem Lauf, welche Schlüssel neu sind — beim typischen Update sind das wenige Prozent
- Übersetzte JSON-Dateien herunterladen
- 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:
- Pakete installieren
- Übersetzungsdateien anlegen
- i18next konfigurieren
useTranslationverwenden- 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.