Skip to main content

Guide till react-intl: konfigurera React-internationalisering

Konfigurera FormatJS react-intl i din React-app med IntlProvider, FormattedMessage, useIntl, ICU-meddelandeformat och automatiserade översättningar.

Använder du react-i18next i stället? Läs vår guide till react-i18next

1

Installera react-intl

react-intl är en del av FormatJS-projektet. Det erbjuder React-komponenter och hooks för att formatera strängar, tal, datum och pluralformer med standarden ICU MessageFormat.

Utöver React har react-intl inga beroenden vid körning. Det använder webbläsarens inbyggda Intl-API för tal- och datumformatering och innehåller en egen ICU MessageFormat-parser för pluralformer, select och formaterad text.
Terminal
npm install react-intl
2

Konfigurera IntlProvider

Omslut appen med IntlProvider vid roten. Skicka in den aktiva språkvarianten och ett platt messages-objekt. Alla underliggande komponenter får sedan åtkomst till översättningar 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 ett platt messages-objekt med nyckelvärdepar (t.ex. { "app.greeting": "Hej" }). Nästlad JSON måste plattas ut innan den skickas till IntlProvider. Du kan också använda ett verktyg som flat för att konvertera nästlade strukturer.

Meddelandefiler

Skapa en JSON-fil per språkvariant. react-intl använder ICU MessageFormat-syntax direkt – pluralformer, select och variabler uttrycks direkt i meddelandesträngarna.

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"
}
Använd punktavgränsade ID:n som "nav.home" för struktur. Till skillnad från react-i18next förväntar sig react-intl ett platt messages-objekt – du plattar ut nycklarna, inte strukturen.
3

Använd översättningar i komponenter

react-intl ger dig två huvudsakliga API:er: komponenten FormattedMessage för att rendera översatt JSX och hooken useIntl för imperativ åtkomst (platshållare, aria-etiketter och programmatisk formatering).

Komponenten FormattedMessage

Använd FormattedMessage för deklarativa översättningar i JSX. Skicka in meddelande-ID:t och eventuella interpoleringsvärden. Den renderar den översatta strängen direkt.

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

Hooken useIntl

Använd useIntl() när du behöver den översatta strängen som ett vanligt värde – för platshållare i inmatningsfält, aria-labels, document.title eller när strängar skickas till API:er utanför React. Den erbjuder också formatNumber, formatDate och 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>
  );
}

Formaterad text (HTML i översättningar)

Bädda in JSX i översättningar med XML-liknande taggar i meddelandesträngarna. Skicka tagghanterare via egenskapen values för att rendera länkar, fetstil eller valfri React-komponent i ett översatt meddelande.

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 renderar ett React Fragment som standard. Om du behöver ett särskilt omslutande element skickar du egenskapen textComponent till IntlProvider eller omsluter FormattedMessage med ett eget element.

Extrahera meddelanden med @formatjs/cli

FormatJS erbjuder ett CLI som automatiskt extraherar meddelande-ID:n från källkoden till en JSON-fil. Det håller meddelandefilen synkroniserad med komponenterna utan manuell hantering.

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 och ICU select

react-intl använder ICU MessageFormat direkt. Pluralformer, genusbaserad select och nästlad formatering uttrycks direkt i meddelandesträngarna – inga suffixkonventioner eller separata nycklar behövs.

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}個の商品があります"
}
Hårdkoda aldrig plurallogik i JavaScript. Språk som arabiska har 6 pluralformer, franska behandlar 0 som singular och japanska saknar pluraldistinktion. Låt ICU MessageFormat hantera reglerna – skicka bara in antalet.

ICU select för genus och roller

Använd ICU select-syntax för översättningar som beror på sammanhang, exempelvis genus, användarroller eller statusvärden. Select-uttrycket väljer rätt variant utifrån det angivna värdet.

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

Automatisera kvalitetskontrollen av översättningar

Upptäck saknade nycklar och trasiga platshållare med i18n-validate innan de når produktion. Testa gränssnittet med pseudoöversättningar via i18n-pseudo innan de riktiga översättningarna är klara.

Vanliga fallgropar

För stor tillit till defaultMessage

defaultMessage är en reservlösning för utveckling, inte en översättningsstrategi. Om du använder defaultMessage för alla strängar innehåller resultatet från meddelandeextraheringen den engelska texten, men översättarna kan missa nya nycklar. Extrahera och underhåll alltid en komplett källspråksfil.

Nästlade objekt i stället för platta nycklar

IntlProvider förväntar sig en platt Record&lt;string, string&gt; för messages. Om du skickar nästlad JSON som { nav: { home: "Hem" } } hittar react-intl inte nyckeln "nav.home". Platta ut meddelandena innan du skickar dem eller använd ett bibliotek som flat.

IntlProvider orsakar omrenderingar

Om du skapar messages-objektet direkt i renderingsfunktionen får IntlProvider en ny objektreferens vid varje rendering, vilket gör att alla konsumenter renderas om. Memoisera messages med useMemo eller definiera objektet utanför komponenten.

IntlProvider saknas i tester

Komponenter som använder FormattedMessage eller useIntl utlöser ett fel om de renderas utan en överordnad IntlProvider. Omslut komponenten med IntlProvider och ange locale="en" samt ett tomt eller minimalt messages-objekt i testerna.

Rekommenderad 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

Prova i18n Agent nu

Släpp din översättningsfil här

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

eller klicka för att välja en fil

Målspråk

Ingen registrering krävsPrisuppskattning direkt

Språkreserv med react-intl-locale-chain

När en översättningsnyckel saknas i en regional språkvariant som pt-BR går react-intl direkt till standardspråket i stället för att först kontrollera det överordnade språket 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>

I vår guide om språkreserver hittar du hela listan över ramverk som stöds och 75 inbyggda kedjor. Learn more →

Vanliga frågor