Skip to main content

Ghid react-intl: configurarea internaționalizării React

Configurați FormatJS react-intl în aplicația React folosind IntlProvider, FormattedMessage, useIntl, formatul mesajelor ICU și traduceri automatizate.

Folosiți în schimb react-i18next? Consultați ghidul nostru react-i18next

1

Instalați react-intl

react-intl face parte din proiectul FormatJS. Acesta oferă componente și hook-uri React pentru formatarea șirurilor, numerelor, datelor și pluralurilor folosind standardul ICU MessageFormat.

În afară de React, react-intl nu are nicio dependență în timpul execuției. Folosește API-ul Intl integrat în browser pentru formatarea numerelor și datelor și include propriul analizor ICU MessageFormat pentru pluraluri, select și text îmbogățit.
Terminal
npm install react-intl
2

Configurați IntlProvider

Încapsulați aplicația cu IntlProvider la nivelul rădăcinii. Transmiteți setarea regională activă și un obiect plat cu mesaje. Fiecare componentă descendentă poate accesa apoi traducerile prin FormattedMessage sau 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 necesită un obiect plat de mesaje cu perechi cheie-valoare (de exemplu, { "app.greeting": "Hello" }). Obiectele JSON imbricate trebuie aplatizate înainte de a fi transmise către IntlProvider; alternativ, folosiți un utilitar precum flat pentru a converti structurile imbricate.

Fișiere de mesaje

Creați câte un fișier JSON pentru fiecare setare regională. react-intl folosește nativ sintaxa ICU MessageFormat — pluralurile, expresiile select și variabilele sunt exprimate direct în șirurile mesajelor.

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"
}
Folosiți ID-uri separate prin puncte, precum „nav.home”, pentru organizare. Spre deosebire de react-i18next, react-intl așteaptă un obiect plat cu mesaje — aplatizați cheile, nu structura.
3

Folosiți traducerile în componente

react-intl vă oferă două API-uri principale: componenta FormattedMessage pentru randarea JSX tradus și hook-ul useIntl pentru acces imperativ (substituenți, etichete aria și formatare programatică).

Componenta FormattedMessage

Folosiți FormattedMessage pentru traduceri declarative în JSX. Transmiteți ID-ul mesajului și valorile de interpolare. Componenta randează direct șirul tradus.

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

Hook-ul useIntl

Folosiți useIntl() când aveți nevoie de șirul tradus ca valoare simplă — pentru substituenții câmpurilor de introducere, etichete aria, document.title sau transmiterea șirurilor către API-uri care nu țin de React. Acesta oferă și formatNumber, formatDate și 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>
  );
}

Text îmbogățit (HTML în traduceri)

Încorporați JSX în traduceri folosind etichete asemănătoare celor XML în șirurile mesajelor. Transmiteți gestionarii etichetelor prin proprietatea values pentru a randa linkuri, text aldin sau orice componentă React într-un mesaj tradus.

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 randează implicit un React Fragment. Dacă aveți nevoie de un anumit element de încadrare, transmiteți proprietatea textComponent către IntlProvider sau încadrați FormattedMessage în propriul element.

Extragerea mesajelor cu @formatjs/cli

FormatJS oferă o interfață CLI pentru extragerea automată a ID-urilor mesajelor din codul sursă într-un fișier JSON. Astfel, fișierul de mesaje rămâne sincronizat cu componentele fără evidență manuală.

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

Pluraluri și ICU select

react-intl folosește nativ ICU MessageFormat. Pluralurile, expresiile select bazate pe gen și formatările imbricate sunt exprimate direct în șirurile mesajelor — fără convenții de sufixe sau chei separate.

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}個の商品があります"
}
Nu introduceți niciodată direct în JavaScript logica de plural. Limbi precum araba au 6 forme de plural, franceza tratează 0 ca singular, iar japoneza nu face distincție între singular și plural. Lăsați ICU MessageFormat să gestioneze regulile — transmiteți doar valoarea numărului.

ICU select pentru gen și roluri

Folosiți sintaxa ICU select pentru traduceri dependente de context, precum genul, rolurile utilizatorilor sau valorile de stare. Expresia select alege varianta corectă în funcție de valoarea furnizată.

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

Automatizați controlul calității traducerilor

Identificați cheile lipsă și substituenții nevalizi înainte de lansare cu i18n-validate. Testați interfața folosind pseudotraduceri cu i18n-pseudo înainte de a primi traducerile reale.

Capcane frecvente

Dependența excesivă de defaultMessage

defaultMessage este un mecanism de rezervă pentru dezvoltare, nu o strategie de traducere. Dacă folosiți defaultMessage pentru toate șirurile, rezultatul extragerii mesajelor va conține textul în engleză, dar traducătorii pot omite cheile noi. Extrageți și întrețineți întotdeauna un fișier-sursă complet pentru setarea regională.

Obiecte imbricate în locul cheilor plate

IntlProvider așteaptă pentru mesaje un Record&lt;string, string&gt; plat. Dacă transmiteți un obiect JSON imbricat precum { nav: { home: "Home" } }, react-intl nu va găsi cheia „nav.home”. Aplatizați mesajele înainte de a le transmite sau folosiți o bibliotecă precum flat.

Rerandări cauzate de IntlProvider

Dacă creați obiectul messages direct în funcția render, IntlProvider primește la fiecare randare o nouă referință la obiect, ceea ce determină rerandarea tuturor consumatorilor. Memorizați messages cu useMemo sau definiți-l în afara componentei.

IntlProvider lipsește din teste

Componentele care folosesc FormattedMessage sau useIntl vor genera o excepție dacă sunt randate fără un strămoș IntlProvider. În teste, încadrați componenta în IntlProvider cu locale="en" și un obiect messages gol sau minimal.

Structura recomandată a fișierelor

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

Încercați acum i18n Agent

Plasați aici fișierul de traducere

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

sau faceți clic pentru a-l selecta

Limbi țintă

Nu este necesară înregistrareaEstimare instantanee

Mecanism de rezervă pentru setările regionale cu react-intl-locale-chain

Când lipsește o cheie de traducere dintr-o setare regională precum pt-BR, react-intl trece direct la setarea regională implicită, fără a verifica mai întâi setarea regională părinte 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>

Consultați Ghidul mecanismelor de rezervă pentru setările regionale pentru lista completă a cadrelor acceptate și a celor 75 de lanțuri integrate. Learn more →

Întrebări frecvente