
دليل react-intl: إعداد التدويل في React
اضبط FormatJS react-intl في تطبيق React لديك باستخدام IntlProvider وFormattedMessage وuseIntl وICU message format والترجمات المؤتمتة.
هل تستخدم react-i18next بدلاً من ذلك؟ اطّلع على دليل react-i18next لدينا
تثبيت react-intl
react-intl جزء من مشروع FormatJS. يوفّر مكوّنات وخطافات React لتنسيق السلاسل النصية والأرقام والتواريخ وصيغ الجمع باستخدام معيار ICU MessageFormat.
npm install react-intlتهيئة IntlProvider
غلِّف تطبيقك بـ IntlProvider عند الجذر. مرِّر اللغة النشطة وكائن رسائل مسطّحاً. عندها يمكن لكل مكوّن في الأسفل الوصول إلى الترجمات عبر FormattedMessage أو 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>
);ملفات الرسائل
أنشئ ملف JSON واحداً لكل لغة. يستخدم react-intl صياغة ICU MessageFormat بشكل أصيل؛ إذ تُكتب صيغ الجمع وselect والمتغيرات كلها مباشرةً داخل سلاسل الرسائل.
// 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"
}استخدام الترجمات في المكوّنات
يقدّم react-intl واجهتَي API أساسيتين: مكوّن FormattedMessage لعرض JSX مترجماً، وخطاف useIntl للوصول الإجرائي (placeholders وaria labels والتنسيق البرنامجي).
مكوّن FormattedMessage
استخدم FormattedMessage للترجمات التصريحية في JSX. مرِّر معرّف الرسالة وأي قيم استبدال. وسيعرض السلسلة المترجمة مباشرةً.
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>
);
}خطاف useIntl
استخدم useIntl() عندما تحتاج إلى السلسلة المترجمة كقيمة عادية؛ مثل placeholders لحقول الإدخال وaria-labels وdocument.title، أو عند تمرير سلاسل نصية إلى API غير تابعة لـ React. كما يوفّر formatNumber وformatDate و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>
);
}النص الغني (HTML في الترجمات)
ضمّن JSX داخل الترجمات باستخدام وسوم شبيهة بـ XML ضمن سلاسل الرسائل. مرِّر معالجات الوسوم عبر الخاصية values لعرض الروابط أو النص العريض أو أي مكوّن React داخل رسالة مترجمة.
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>,
}}
/>
);
}استخراج الرسائل باستخدام @formatjs/cli
يوفّر FormatJS أداة CLI لاستخراج معرّفات الرسائل تلقائياً من شفرتك المصدرية إلى ملف JSON. يضمن ذلك بقاء ملف الرسائل متزامناً مع مكوّناتك دون متابعة يدوية.
# 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صيغ الجمع وICU Select
يستخدم react-intl صياغة ICU MessageFormat بشكل أصيل. تُعبَّر صيغ الجمع وselect القائم على النوع والتنسيق المتداخل مباشرةً داخل سلاسل الرسائل؛ ولا حاجة إلى اصطلاحات لواحق أو مفاتيح منفصلة.
// 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 للنوع والأدوار
استخدم صياغة ICU select للترجمات المعتمدة على السياق مثل النوع وأدوار المستخدم أو قيم الحالة. يختار تعبير select المتغير الصحيح بناءً على القيمة المقدَّمة.
// 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 }}
/>أتمتة جودة الترجمة
المزالق الشائعة
الاعتماد المفرط على defaultMessage
كائنات متداخلة بدلاً من مفاتيح مسطّحة
IntlProvider يسبّب إعادة العرض
غياب IntlProvider في الاختبارات
هيكل الملفات الموصى به
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جرّب i18n Agent الآن
أفلت ملف الترجمة هنا
JSON, YAML, PO, XML, CSV, Markdown, Properties
أو انقر للاستعراض
اللغات المستهدفة
الرجوع الاحتياطي للغة باستخدام react-intl-locale-chain
عندما يكون مفتاح ترجمة مفقوداً في لغة إقليمية مثل pt-BR، ينتقل react-intl مباشرةً إلى اللغة الافتراضية بدلاً من التحقق أولاً من اللغة الأم pt.
npm install react-intl-locale-chain<LocaleChainProvider
fallbacks={{
'pt-BR': ['pt', 'en'],
'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
}}
defaultLocale="en"
>
<App />
</LocaleChainProvider>اطّلع على دليل الرجوع الاحتياطي للغة لدينا للاطلاع على القائمة الكاملة للأُطر المدعومة و75 سلسلة مدمجة. Learn more →