Skip to main content

react-intl vadovas: React internacionalizavimo sąranka

Sukonfigūruokite FormatJS react-intl React programoje su IntlProvider, FormattedMessage, useIntl, ICU pranešimų formatu ir automatizuotais vertimais.

Vietoje to naudojate react-i18next? Peržiūrėti mūsų react-i18next vadovą

1

Įdiegti react-intl

react-intl yra FormatJS projekto dalis. Ji suteikia React komponentus ir kablius eilutėms, skaičiams, datoms bei daugiskaitai formatuoti pagal ICU MessageFormat standartą.

Be React react-intl neturi jokių vykdymo priklausomybių. Skaičiams ir datoms formatuoti ji naudoja integruotą naršyklės Intl API, o daugiskaitai, pasirinkimui ir raiškiajam tekstui pateikia savo ICU MessageFormat analizatorių.
Terminal
npm install react-intl
2

Sukonfigūruoti IntlProvider

Apgaubkite programą IntlProvider šaknyje. Perduokite aktyvią lokalę ir plokščią pranešimų objektą. Tada kiekvienas žemiau esantis komponentas galės pasiekti vertimus per FormattedMessage arba 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 reikia plokščio raktų ir reikšmių pranešimų objekto (pvz., { "app.greeting": "Hello" }). Prieš perduodant IntlProvider įdėtinį JSON reikia suplokštinti arba įdėtines struktūras konvertuoti tokia priemone kaip flat.

Pranešimų failai

Sukurkite po vieną JSON failą kiekvienai lokalei. react-intl savaime naudoja ICU MessageFormat sintaksę: daugiskaita, pasirinkimas ir kintamieji išreiškiami tiesiogiai pranešimų eilutėse.

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"
}
Tvarkai naudokite taškais atskirtus ID, pavyzdžiui, „nav.home“. Kitaip nei react-i18next, react-intl tikisi plokščio pranešimų objekto: suplokštinate raktus, o ne struktūrą.
3

Naudoti vertimus komponentuose

react-intl suteikia dvi pagrindines API: komponentą FormattedMessage išverstam JSX atvaizduoti ir kablį useIntl imperatyviai prieigai (vietos rezervavimo ženklams, aria etiketėms, programiniam formatavimui).

FormattedMessage komponentas

Naudokite FormattedMessage deklaratyviems vertimams JSX. Perduokite pranešimo ID ir visas interpoliavimo reikšmes. Jis tiesiogiai atvaizduoja išverstą eilutę.

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

useIntl kablys

Naudokite useIntl(), kai išverstos eilutės reikia kaip paprastos reikšmės: įvesties laukų vietos rezervavimo ženklams, aria-label, document.title arba perduodant eilutes ne React API. Jis taip pat suteikia formatNumber, formatDate ir 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>
  );
}

Raiškusis tekstas (HTML vertimuose)

Įterpkite JSX į vertimus naudodami į XML panašias žymas pranešimų eilutėse. Perduokite žymų apdorojimo įrankius per ypatybę values, kad išverstame pranešime atvaizduotumėte nuorodas, pusjuodį tekstą ar bet kurį React komponentą.

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>,
      }}
    />
  );
}
Pagal numatytąją nuostatą FormattedMessage atvaizduoja React Fragment. Jei reikia konkretaus apgaubiančio elemento, perduokite ypatybę textComponent į IntlProvider arba apgaubkite FormattedMessage savo elementu.

Pranešimų išskyrimas su @formatjs/cli

FormatJS suteikia CLI, kuris automatiškai išskiria pranešimų ID iš pirminio kodo į JSON failą. Taip pranešimų failas lieka sinchronizuotas su komponentais be rankinio tvarkymo.

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

Daugiskaita ir ICU pasirinkimas

react-intl savaime naudoja ICU MessageFormat. Daugiskaita, gimine pagrįstas pasirinkimas ir įdėtinis formatavimas išreiškiami tiesiogiai pranešimų eilutėse – nereikia priesagų susitarimų ar atskirų raktų.

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}個の商品があります"
}
Niekada tiesiogiai neįrašykite daugiskaitos logikos JavaScript. Arabų kalboje yra 6 daugiskaitos formos, prancūzų kalboje 0 laikomas vienaskaita, o japonų kalboje daugiskaita visai neskiriama. Leiskite taisykles apdoroti ICU MessageFormat – tiesiog perduokite skaičiaus reikšmę.

ICU pasirinkimas giminei ir vaidmenims

Naudokite ICU pasirinkimo sintaksę nuo konteksto priklausantiems vertimams, pavyzdžiui, giminei, naudotojo vaidmenims ar būsenos reikšmėms. Pasirinkimo išraiška parenka tinkamą variantą pagal pateiktą reikšmę.

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

Automatizuoti vertimo kokybę

Naudodami i18n-validate prieš išleidimą aptikite trūkstamus raktus ir sugadintus vietos rezervavimo ženklus. Kol dar nėra tikrų vertimų, patikrinkite UI su i18n-pseudo pseudoverstimais.

Dažnos klaidos

Per didelis pasikliovimas defaultMessage

defaultMessage yra kūrimo atsarginis variantas, o ne vertimo strategija. Jei defaultMessage naudojate visoms eilutėms, pranešimų išskyrimo išvestyje bus angliškas tekstas, tačiau vertėjai gali nepastebėti naujų raktų. Visada išskirkite ir prižiūrėkite išsamų šaltinio lokalės failą.

Įdėtiniai objektai vietoje plokščių raktų

IntlProvider tikisi plokščio Record&lt;string, string&gt; objektui messages. Jei perduosite įdėtinį JSON, pavyzdžiui, { nav: { home: "Home" } }, react-intl neras rakto „nav.home“. Prieš perduodami suplokštinkite pranešimus arba naudokite tokią biblioteką kaip flat.

IntlProvider sukelia pakartotinį atvaizdavimą

Jei objektą messages sukuriate tiesiogiai atvaizdavimo funkcijoje, IntlProvider kiekvieną kartą gauna naują objekto nuorodą, todėl visi vartotojai atvaizduojami iš naujo. Įsiminkite messages su useMemo arba apibrėžkite už komponento ribų.

Testuose trūksta IntlProvider

FormattedMessage arba useIntl naudojantys komponentai pateiks klaidą, jei bus atvaizduoti be pirminio IntlProvider. Testuose apgaubkite komponentą IntlProvider su locale="en" ir tuščiu arba minimaliu objektu messages.

Rekomenduojama failų struktūra

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

Išbandykite i18n Agent dabar

Nuvilkite vertimo failą čia

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

arba spustelėkite norėdami pasirinkti

Tikslinės kalbos

Registruotis nereikiaMomentinis įvertis

Atsarginė lokalė su react-intl-locale-chain

Kai regioninėje lokalėje, pavyzdžiui, pt-BR, trūksta vertimo rakto, react-intl iškart pereina prie numatytosios lokalės, užuot pirmiausia patikrinęs pirminę lokalę 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>

Visą palaikomų sistemų sąrašą ir 75 integruotas grandines rasite mūsų atsarginių lokalių vadove. Learn more →

Dažnai užduodami klausimai