Skip to main content

Guide til react-intl: Opsæt internationalisering i React

Opsæt FormatJS react-intl i din React-app med IntlProvider, FormattedMessage, useIntl, ICU-meddelelsesformat og automatiske oversættelser.

Bruger du react-i18next i stedet? Se vores guide til react-i18next

1

Installer react-intl

react-intl er en del af FormatJS-projektet. Det leverer React-komponenter og hooks til formatering af strenge, tal, datoer og pluralformer med ICU MessageFormat-standarden.

react-intl har ingen kørselsafhængigheder ud over React. Det bruger browserens indbyggede Intl API til formatering af tal og datoer og leverer sin egen ICU MessageFormat-parser til pluralformer, select og formateret tekst.
Terminal
npm install react-intl
2

Konfigurer IntlProvider

Ombryd din app med IntlProvider ved roden. Angiv den aktive landestandard og et fladt messages-objekt. Alle underliggende komponenter kan derefter tilgå oversættelser via FormattedMessage eller useIntl.

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 kræver et fladt messages-objekt med nøgleværdipar (f.eks. { "app.greeting": "Hello" }). Indlejret JSON skal flades ud, før det overføres til IntlProvider. Du kan også bruge et hjælpeværktøj som flat til at konvertere indlejrede strukturer.

Meddelelsesfiler

Opret én JSON-fil pr. landestandard. react-intl bruger ICU MessageFormat-syntaks direkte – pluralformer, select og variabler udtrykkes alle direkte i meddelelsesstrengene.

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"
}
Brug punktumadskilte id'er som "nav.home" til organisering. I modsætning til react-i18next forventer react-intl et fladt messages-objekt – du flader nøglerne ud, ikke strukturen.
3

Brug oversættelser i komponenter

react-intl giver dig to primære API'er: Komponenten FormattedMessage til gengivelse af oversat JSX og hooket useIntl til imperativ adgang (pladsholdere, aria-labels og programmatisk formatering).

Komponenten FormattedMessage

Brug FormattedMessage til deklarative oversættelser i JSX. Angiv meddelelses-id'et og eventuelle interpolationsværdier. Komponenten gengiver den oversatte streng direkte.

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>
  );
}

Hooket useIntl

Brug useIntl(), når du skal bruge den oversatte streng som en almindelig værdi – til inputpladsholdere, aria-labels, document.title eller overførsel af strenge til API'er uden for React. Det giver også adgang til formatNumber, formatDate og formatRelativeTime.

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>
  );
}

Formateret tekst (HTML i oversættelser)

Indlejr JSX i oversættelser ved hjælp af XML-lignende tags i dine meddelelsesstrenge. Overfør taghandlers via proppen values for at gengive links, fed tekst eller en vilkårlig React-komponent i en oversat meddelelse.

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 gengiver som standard et React Fragment. Hvis du har brug for et bestemt omslutningselement, kan du angive proppen textComponent på IntlProvider eller omslutte FormattedMessage med dit eget element.

Udtræk meddelelser med @formatjs/cli

FormatJS leverer en CLI, der automatisk udtrækker meddelelses-id'er fra din kildekode til en JSON-fil. Det holder din meddelelsesfil synkroniseret med dine komponenter uden manuel administration.

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

Pluralformer og ICU Select

react-intl bruger ICU MessageFormat direkte. Pluralformer, kønsbaseret select og indlejret formatering udtrykkes alle direkte i meddelelsesstrengene – der kræves ingen suffikskonventioner eller separate nøgler.

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}個の商品があります"
}
Indkod aldrig plurallogik direkte i JavaScript. Sprog som arabisk har 6 pluralformer, fransk behandler 0 som ental og japansk skelner ikke mellem pluralformer. Lad ICU MessageFormat håndtere reglerne – du skal blot angive antalsværdien.

ICU Select til køn og roller

Brug ICU select-syntaks til kontekstafhængige oversættelser som køn, brugerroller eller statusværdier. select-udtrykket vælger den rigtige variant ud fra den angivne værdi.

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 }}
/>

Automatiser oversættelseskvaliteten

Find manglende nøgler og ugyldige pladsholdere med i18n-validate, før de udgives. Test din brugergrænseflade med pseudooversættelser ved hjælp af i18n-pseudo, før de rigtige oversættelser er klar.

Almindelige faldgruber

For stor afhængighed af defaultMessage

defaultMessage er en reserve under udvikling, ikke en oversættelsesstrategi. Hvis du bruger defaultMessage til alle strenge, indeholder resultatet af meddelelsesudtrækket den engelske tekst, men oversættere kan overse nye nøgler. Udtræk og vedligehold altid en komplet kildelandestandardfil.

Indlejrede objekter i stedet for flade nøgler

IntlProvider forventer en flad Record&lt;string, string&gt; til messages. Hvis du overfører indlejret JSON som { nav: { home: "Home" } }, kan react-intl ikke finde nøglen "nav.home". Flad dine meddelelser ud, før du overfører dem eller brug et bibliotek som flat.

IntlProvider medfører nye gengivelser

Hvis du opretter messages-objektet direkte i gengivelsesfunktionen, modtager IntlProvider en ny objektreference ved hver gengivelse, hvilket får alle forbrugere til at blive gengivet igen. Memoiser messages med useMemo eller definer det uden for komponenten.

Manglende IntlProvider i test

Komponenter, der bruger FormattedMessage eller useIntl, udløser en fejl, hvis de gengives uden en overordnet IntlProvider. I test skal du omslutte din komponent med IntlProvider med locale="en" og et tomt eller minimalt messages-objekt.

Anbefalet filstruktur

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

Prøv i18n Agent nu

Slip din oversættelsesfil her

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

eller klik for at vælge en fil

Målsprog

Kræver ingen tilmeldingEstimat med det samme

landestandardreserve med react-intl-locale-chain

Når en oversættelsesnøgle mangler i en regional landestandard som pt-BR, går react-intl direkte til standardlandestandarden i stedet for først at kontrollere den overordnede landestandard pt.

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>

Se vores guide til landestandardreserver for at få den komplette liste over understøttede frameworks og 75 indbyggede kæder. Learn more →

Ofte stillede spørgsmål