Skip to main content

react-intl-Leitfaden: React-Internationalisierung einrichten

Richten Sie FormatJS react-intl in Ihrer React-App mit IntlProvider, FormattedMessage, useIntl, ICU-Nachrichtenformat und automatisierten Übersetzungen ein.

Verwenden Sie stattdessen react-i18next? Lesen Sie unseren react-i18next-Leitfaden

1

react-intl installieren

react-intl ist Teil des FormatJS-Projekts. Es stellt React-Komponenten und -Hooks bereit, um Zeichenfolgen, Zahlen, Datumswerte und Pluralformen nach dem ICU-MessageFormat-Standard zu formatieren.

react-intl besitzt außer React keine Laufzeitabhängigkeiten. Die Bibliothek nutzt die integrierte Intl-API des Browsers zur Zahlen- und Datumsformatierung und enthält einen eigenen ICU-MessageFormat-Parser für Pluralformen, select und Rich Text.
Terminal
npm install react-intl
2

IntlProvider konfigurieren

Umschließen Sie Ihre App im Stamm mit IntlProvider. Übergeben Sie die aktive Locale und ein flaches messages-Objekt. Jede untergeordnete Komponente kann anschließend über FormattedMessage oder useIntl auf Übersetzungen zugreifen.

src/main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { IntlProvider } from 'react-intl';
import App from './App';
import enMessages from './messages/en.json';
import deMessages from './messages/de.json';

const messages: Record<string, Record<string, string>> = {
  en: enMessages,
  de: deMessages,
};

// Detect locale from browser or your routing layer
const locale = navigator.language.split('-')[0] || 'en';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <IntlProvider locale={locale} messages={messages[locale] || messages.en}>
      <App />
    </IntlProvider>
  </React.StrictMode>
);
IntlProvider benötigt ein flaches messages-Objekt mit Schlüssel-Wert-Paaren, beispielsweise { "app.greeting": "Hello" }. Verschachteltes JSON muss vor der Übergabe an IntlProvider abgeflacht werden; alternativ können Sie Strukturen mit einem Hilfsprogramm wie flat konvertieren.

Nachrichtendateien

Erstellen Sie eine JSON-Datei pro Locale. react-intl verwendet die ICU-MessageFormat-Syntax nativ; Pluralformen, select und Variablen werden inline in Nachrichtenzeichenfolgen ausgedrückt.

messages/en.json & messages/de.json
// messages/en.json
{
  "app.greeting": "Hello, {name}!",
  "nav.home": "Home",
  "nav.about": "About",
  "nav.settings": "Settings",
  "cart.itemCount": "{count, plural, one {# item} other {# items}} in your cart"
}

// messages/de.json
{
  "app.greeting": "Hallo, {name}!",
  "nav.home": "Startseite",
  "nav.about": "Über uns",
  "nav.settings": "Einstellungen",
  "cart.itemCount": "{count, plural, one {# Artikel} other {# Artikel}} in Ihrem Warenkorb"
}
Verwenden Sie zur Gliederung durch Punkte getrennte IDs wie „nav.home“. Anders als react-i18next erwartet react-intl ein flaches messages-Objekt – Sie flachen die Schlüssel ab, nicht die Struktur.
3

Übersetzungen in Komponenten verwenden

react-intl bietet zwei zentrale APIs: die Komponente FormattedMessage zum Rendern übersetzten JSX und den Hook useIntl für imperativen Zugriff, etwa bei Platzhaltern, aria-Bezeichnungen und programmatischer Formatierung.

FormattedMessage-Komponente

Verwenden Sie FormattedMessage für deklarative Übersetzungen in JSX. Übergeben Sie die Nachrichten-ID und mögliche Interpolationswerte. Die übersetzte Zeichenfolge wird direkt gerendert.

Greeting.tsx
import { FormattedMessage } from 'react-intl';

function Greeting({ userName }: { userName: string }) {
  return (
    <div>
      <h1>
        <FormattedMessage
          id="app.greeting"
          values={{ name: userName }}
        />
      </h1>
      <nav>
        <a href="/"><FormattedMessage id="nav.home" /></a>
        <a href="/about"><FormattedMessage id="nav.about" /></a>
      </nav>
    </div>
  );
}

useIntl-Hook

Verwenden Sie useIntl(), wenn Sie die übersetzte Zeichenfolge als einfachen Wert benötigen – für Eingabeplatzhalter, aria-labels, document.title oder zur Übergabe an APIs außerhalb von React. Der Hook stellt außerdem formatNumber, formatDate und formatRelativeTime bereit.

SearchBar.tsx
import { useIntl } from 'react-intl';

function SearchBar() {
  const intl = useIntl();

  return (
    <input
      type="search"
      placeholder={intl.formatMessage({ id: 'search.placeholder' })}
      aria-label={intl.formatMessage({ id: 'search.ariaLabel' })}
    />
  );
}

// useIntl also gives you formatNumber, formatDate, formatRelativeTime:
function PriceTag({ amount, currency }: { amount: number; currency: string }) {
  const intl = useIntl();
  return (
    <span>{intl.formatNumber(amount, { style: 'currency', currency })}</span>
  );
}

Rich Text (HTML in Übersetzungen)

Betten Sie JSX mit XML-ähnlichen Tags in Ihre Nachrichtenzeichenfolgen ein. Übergeben Sie Tag-Handler über die values-Prop, um Links, Fettschrift oder beliebige React-Komponenten innerhalb einer übersetzten Nachricht zu rendern.

SignUp.tsx
import { FormattedMessage } from 'react-intl';

// Message: "By signing up, you agree to our <link>Terms</link>."
// Key: "signup.terms"
// Value: "By signing up, you agree to our <link>Terms</link>."

function SignUp() {
  return (
    <FormattedMessage
      id="signup.terms"
      values={{
        link: (chunks) => <a href="/terms" className="underline">{chunks}</a>,
      }}
    />
  );
}
FormattedMessage rendert standardmäßig ein React Fragment. Wenn Sie ein bestimmtes umschließendes Element benötigen, übergeben Sie die Prop textComponent an IntlProvider oder umschließen Sie FormattedMessage mit einem eigenen Element.

Nachrichtenextraktion mit @formatjs/cli

FormatJS bietet eine CLI, die Nachrichten-IDs automatisch aus Ihrem Quellcode in eine JSON-Datei extrahiert. So bleibt Ihre Nachrichtendatei ohne manuelle Pflege mit Ihren Komponenten synchron.

Terminal
# Install the CLI
npm install -g @formatjs/cli

# Extract messages from source code into a JSON file
formatjs extract 'src/**/*.tsx' --out-file messages/en.json --id-interpolation-pattern '[sha512:contenthash:base64:6]'

# Or use explicit IDs (recommended):
formatjs extract 'src/**/*.tsx' --out-file messages/en.json

# Compile messages for production (optional, improves perf)
formatjs compile messages/en.json --out-file compiled/en.json
formatjs compile messages/de.json --out-file compiled/de.json
4

Pluralformen und ICU select

react-intl verwendet ICU MessageFormat nativ. Pluralformen, geschlechtsbezogenes select und verschachtelte Formatierung werden direkt in Nachrichtenzeichenfolgen ausgedrückt – Suffixkonventionen oder eigene Schlüssel sind nicht erforderlich.

ICU plural syntax by language
// ICU MessageFormat syntax — react-intl uses this natively
// English
{
  "cart.itemCount": "{count, plural, one {# item} other {# items}} in your cart",
  "inbox.unread": "You have {count, plural, =0 {no unread messages} one {# unread message} other {# unread messages}}"
}

// Arabic — 6 plural forms
{
  "cart.itemCount": "{count, plural, zero {لا عناصر} one {عنصر واحد} two {عنصران} few {# عناصر} many {# عنصرًا} other {# عنصر}} في سلتك"
}

// Japanese — 1 form (other)
{
  "cart.itemCount": "カートに{count}個の商品があります"
}
Codieren Sie Plurallogik niemals fest in JavaScript. Sprachen wie Arabisch besitzen sechs Pluralformen, Französisch behandelt 0 als Singular und Japanisch unterscheidet keine Pluralformen. Überlassen Sie die Regeln ICU MessageFormat und übergeben Sie lediglich den count-Wert.

ICU select für Geschlecht und Rollen

Verwenden Sie die ICU-select-Syntax für kontextabhängige Übersetzungen, etwa Geschlecht, Benutzerrollen oder Statuswerte. Der select-Ausdruck wählt anhand des übergebenen Werts die richtige Variante aus.

ICU select syntax
// Gender-dependent messages using ICU select
{
  "user.greeting": "{gender, select, male {He} female {She} other {They}} liked your post.",
  "user.invitation": "{role, select, admin {You can manage all settings.} editor {You can edit content.} other {You can view content.}}"
}

// Usage:
<FormattedMessage
  id="user.greeting"
  values={{ gender: user.gender }}
/>

Übersetzungsqualität automatisieren

Erkennen Sie mit i18n-validate fehlende Schlüssel und beschädigte Platzhalter vor der Veröffentlichung. Testen Sie Ihre Benutzeroberfläche mit i18n-pseudo und Pseudoübersetzungen, bevor echte Übersetzungen vorliegen.

Häufige Fallstricke

Zu stark auf defaultMessage vertrauen

defaultMessage ist ein Fallback für die Entwicklung, keine Übersetzungsstrategie. Wenn Sie defaultMessage für sämtliche Zeichenfolgen verwenden, enthält Ihre Extraktionsausgabe zwar den englischen Text, doch neue Schlüssel können bei der Übersetzung übersehen werden. Extrahieren und pflegen Sie stets eine vollständige Datei der Ausgangs-Locale.

Verschachtelte Objekte statt flacher Schlüssel

IntlProvider erwartet für messages ein flaches Record&lt;string, string&gt;. Wenn Sie verschachteltes JSON wie { nav: { home: "Home" } } übergeben, findet react-intl den Schlüssel „nav.home“ nicht. Flachen Sie Ihre Nachrichten vor der Übergabe ab oder verwenden Sie eine Bibliothek wie flat.

IntlProvider verursacht erneutes Rendern

Wenn Sie das messages-Objekt inline in der Renderfunktion erstellen, erhält IntlProvider bei jedem Rendern eine neue Objektreferenz. Dadurch werden alle Verbraucher erneut gerendert. Speichern Sie messages mit useMemo zwischen oder definieren Sie es außerhalb der Komponente.

IntlProvider fehlt in Tests

Komponenten mit FormattedMessage oder useIntl lösen beim Rendern ohne übergeordneten IntlProvider einen Fehler aus. Umschließen Sie Ihre Komponente in Tests mit IntlProvider, locale="en" und einem leeren oder minimalen messages-Objekt.

Empfohlene Dateistruktur

Project Structure
my-react-app/
├── messages/
│   ├── en.json              # Source of truth (English)
│   ├── de.json              # German
│   ├── ja.json              # Japanese
│   └── es.json              # Spanish
├── compiled/                # Optional: compiled messages for prod
│   ├── en.json
│   └── ...
├── src/
│   ├── main.tsx             # App entry with IntlProvider
│   ├── App.tsx
│   └── components/
│       ├── Greeting.tsx      # Uses FormattedMessage
│       └── SearchBar.tsx     # Uses useIntl
└── package.json

i18n Agent jetzt testen

Legen Sie Ihre Übersetzungsdatei hier ab

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

oder zum Auswählen klicken

Zielsprachen

Keine Registrierung erforderlichSofortiges Angebot

Locale-Fallback mit react-intl-locale-chain

Fehlt ein Übersetzungsschlüssel in einer regionalen Locale wie pt-BR, wechselt react-intl direkt zur Standard-Locale, statt zuerst die übergeordnete Locale pt zu prüfen.

Terminal
npm install react-intl-locale-chain
Configuration
<LocaleChainProvider
  fallbacks={{
    'pt-BR': ['pt', 'en'],
    'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
  }}
  defaultLocale="en"
>
  <App />
</LocaleChainProvider>

In unserem Leitfaden zu Locale-Fallbacks finden Sie die vollständige Liste unterstützter Frameworks und 75 integrierter Ketten. Learn more →

Häufig gestellte Fragen