
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
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.
npm install react-intlConfiguraț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.
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>
);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
{
"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 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.
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.
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.
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>,
}}
/>
);
}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ă.
# 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.jsonPluraluri ș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 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}個の商品があります"
}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ă.
// 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
Capcane frecvente
Dependența excesivă de defaultMessage
Obiecte imbricate în locul cheilor plate
Rerandări cauzate de IntlProvider
IntlProvider lipsește din teste
Structura recomandată a fișierelor
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ă
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.
npm install react-intl-locale-chain<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 →