
Panduan react-intl: Persediaan Pengantarabangsaan React
Sediakan react-intl daripada FormatJS dalam aplikasi React dengan IntlProvider, FormattedMessage, useIntl, format mesej ICU, dan terjemahan automatik.
Menggunakan react-i18next? Lihat panduan react-i18next kami
Pasang react-intl
react-intl ialah sebahagian daripada projek FormatJS. Pustaka ini menyediakan komponen dan cangkuk React untuk memformat rentetan, nombor, tarikh, dan bentuk jamak menggunakan standard ICU MessageFormat.
npm install react-intlKonfigurasikan IntlProvider
Balut aplikasi dengan IntlProvider pada akar. Teruskan bahasa aktif dan objek messages rata. Setiap komponen di bawahnya kemudian boleh mengakses terjemahan melalui FormattedMessage atau 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>
);Fail Mesej
Cipta satu fail JSON bagi setiap bahasa. react-intl menggunakan sintaks ICU MessageFormat secara natif—bentuk jamak, select, dan pemboleh ubah semuanya dinyatakan sebaris dalam rentetan mesej.
// 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"
}Gunakan Terjemahan dalam Komponen
react-intl menyediakan dua API utama: komponen FormattedMessage untuk memaparkan JSX terjemahan dan cangkuk useIntl untuk akses imperatif (ruang letak, label aria, pemformatan berprogram).
Komponen FormattedMessage
Gunakan FormattedMessage untuk terjemahan deklaratif dalam JSX. Teruskan ID mesej dan sebarang nilai interpolasi. Komponen memaparkan rentetan terjemahan secara langsung.
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>
);
}Cangkuk useIntl
Gunakan useIntl() apabila memerlukan rentetan terjemahan sebagai nilai biasa—untuk ruang letak input, label aria, document.title, atau apabila meneruskan rentetan kepada API bukan React. Cangkuk juga menyediakan formatNumber, formatDate, dan 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>
);
}Teks Kaya (HTML dalam Terjemahan)
Benamkan JSX dalam terjemahan menggunakan teg seperti XML dalam rentetan mesej. Teruskan pengendali teg melalui prop values untuk memaparkan pautan, teks tebal, atau sebarang komponen React dalam mesej terjemahan.
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>,
}}
/>
);
}Pengekstrakan Mesej dengan @formatjs/cli
FormatJS menyediakan CLI untuk mengekstrak ID mesej secara automatik daripada kod sumber ke dalam fail JSON. Ini memastikan fail mesej kekal segerak dengan komponen tanpa pencatatan 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.jsonBentuk Jamak dan ICU Select
react-intl menggunakan ICU MessageFormat secara natif. Bentuk jamak, select berasaskan jantina, dan pemformatan tersarang semuanya dinyatakan terus dalam rentetan mesej—tanpa konvensyen akhiran atau kekunci berasingan.
// 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 untuk Jantina dan Peranan
Gunakan sintaks ICU select untuk terjemahan bergantung pada konteks seperti jantina, peranan pengguna, atau nilai keadaan. Ungkapan select memilih varian yang betul berdasarkan nilai yang diberikan.
// 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 }}
/>Automatikkan Kualiti Terjemahan
Kesilapan Umum
Terlalu Bergantung pada defaultMessage
Objek Tersarang, Bukan Kekunci Rata
IntlProvider Menyebabkan Paparan Semula
IntlProvider Hilang dalam Ujian
Struktur Fail yang Disyorkan
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.jsonCuba i18n Agent Sekarang
Lepaskan fail terjemahan anda di sini
JSON, YAML, PO, XML, CSV, Markdown, Properties
atau klik untuk semak imbas
Bahasa sasaran
Sandaran Bahasa dengan react-intl-locale-chain
Apabila kekunci terjemahan tiada dalam bahasa serantau seperti pt-BR, react-intl terus beralih kepada bahasa lalai dan bukannya memeriksa bahasa induk pt terlebih dahulu.
npm install react-intl-locale-chain<LocaleChainProvider
fallbacks={{
'pt-BR': ['pt', 'en'],
'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
}}
defaultLocale="en"
>
<App />
</LocaleChainProvider>Lihat Panduan Sandaran Bahasa kami untuk senarai lengkap rangka kerja yang disokong dan 75 rantaian terbina dalam. Learn more →