Skip to main content

Pilnīgs React internacionalizācijas ceļvedis

No nulles līdz vairākām valodām: iestatiet i18n React lietotnē, pēc tam automatizējiet tulkošanu ar MI.

1

Instalēt pakotnes

Vajadzīgas trīs pakotnes: react-i18next (React saistījumi), i18next (pamatbibliotēka) un pēc izvēles i18next-browser-languagedetector automātiskai lokalizācijas noteikšanai.

react-i18next nodrošina React āķus un komponentus. i18next ir pamatdzinējs, kas apstrādā tulkojumu ielādi, interpolāciju un daudzskaitli. Valodas noteikšanas spraudnis automātiski nolasa pārlūkā izvēlēto valodu.
Terminal
npm install react-i18next i18next i18next-browser-languagedetector i18next-http-backend
2

Konfigurēt i18n instanci

Izveidojiet i18n konfigurācijas failu, kas inicializē i18next ar noklusējuma valodu, tulkošanas resursiem un spraudņu ķēdi. Šis fails jāimportē lietotnes ieejas punktā, pirms tiek atveidots jebkurš komponents.

src/i18n.ts
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import Backend from 'i18next-http-backend';

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)  // Must come before .init()
  .init({
    fallbackLng: 'en',
    debug: process.env.NODE_ENV === 'development',
    interpolation: {
      escapeValue: false,  // React already escapes
    },
    backend: {
      loadPath: '/locales/{{lng}}/{{ns}}.json',
    },
  });

export default i18n;
„You will need to pass in an i18next instance by using initReactI18next“ — šī kļūda nozīmē, ka pirms i18n.init() aizmirsāt izsaukt i18n.use(initReactI18next). .use() jāizsauc pirms .init().
3

Ietvert lietotni I18nextProvider

Importējiet i18n konfigurācijas failu lietotnes saknē un ietveriet komponentu koku ar I18nextProvider. Bez tā useTranslation() atgriež neapstrādātas atslēgas, nevis tulkotu tekstu.

src/main.tsx
import React, { Suspense } from 'react';
import ReactDOM from 'react-dom/client';
import { I18nextProvider } from 'react-i18next';
import i18n from './i18n';  // Import your config
import App from './App';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <Suspense fallback={<div>Loading...</div>}>
      <I18nextProvider i18n={i18n}>
        <App />
      </I18nextProvider>
    </Suspense>
  </React.StrictMode>
);
Ja tulkojumu vietā tiek rādītas neapstrādātas atslēgas, piemēram, „welcome“, nevis „Laipni lūdzam mūsu lietotnē“, visbiežāk trūkst I18nextProvider vai nav importēts i18n konfigurācijas fails.
4

Izveidot tulkošanas failus

Izveidojiet vienu JSON failu katrai valodai. Sakārtojiet virknes pēc funkcijas vai lapas, izmantojot ligzdotas atslēgas. Avota valodu (parasti angļu) uzturiet kā vienīgo patiesības avotu.

public/locales/en/translation.json
// public/locales/en/translation.json
{
  "nav": {
    "home": "Home",
    "about": "About",
    "settings": "Settings"
  },
  "greeting": "Hello, {{name}}!",
  "cart": {
    "itemCount_one": "{{count}} item",
    "itemCount_other": "{{count}} items"
  }
}

// public/locales/de/translation.json
{
  "nav": {
    "home": "Startseite",
    "about": "Über uns",
    "settings": "Einstellungen"
  },
  "greeting": "Hallo, {{name}}!",
  "cart": {
    "itemCount_one": "{{count}} Artikel",
    "itemCount_other": "{{count}} Artikel"
  }
}
Nosauciet atslēgas pēc tā, ko tās apraksta, nevis kur tās parādās: „cart.itemCount“ ir labāks par „homepageCartLabel“. Atslēgām jāiztur UI pārveide.
5

Izmantot tulkojumus komponentos

Izsauciet useTranslation() jebkurā komponentā, lai iegūtu funkciju t(). Izmantojiet to vienkāršām virknēm, interpolētiem mainīgajiem un JSX iegultiem tulkojumiem ar komponentu Trans.

Greeting.tsx
import { useTranslation } from 'react-i18next';

function Greeting({ userName }: { userName: string }) {
  const { t } = useTranslation();

  return (
    <div>
      <h1>{t('greeting', { name: userName })}</h1>
      <nav>
        <a href="/">{t('nav.home')}</a>
        <a href="/about">{t('nav.about')}</a>
      </nav>
    </div>
  );
}
Trans component for JSX
import { Trans, useTranslation } from 'react-i18next';

// For JSX inside translations:
// "terms": "By signing up, you agree to our <link>Terms</link>."

function SignUp() {
  const { t } = useTranslation();
  return (
    <Trans i18nKey="terms" components={{
      link: <a href="/terms" className="underline" />
    }} />
  );
}
Dinamiskas atslēgas, piemēram, t(`error.$'{code}'`), darbojas izpildlaikā, taču tādi rīki kā i18next-scanner nevar tās statiski izvilkt. Ja izmantojat izvilkšanas rīkus, skaidri uzskaitiet dinamiskās atslēgas vai izmantojiet komentāra norādi.
6

Apstrādāt daudzskaitli un mainīgos

i18next apstrādā daudzskaitli atbilstoši CLDR kārtulām, nevis tikai vienskaitlim un daudzskaitlim. Arābu valodā ir 6 formas (zero, one, two, few, many, other), japāņu — 1 (other). Definējiet visas vajadzīgās formas tulkošanas failos, un i18next automātiski izvēlēsies pareizo.

Plural forms by language
// English: 2 forms (one, other)
{
  "itemCount_one": "{{count}} item",
  "itemCount_other": "{{count}} items"
}

// Arabic: 6 forms (zero, one, two, few, many, other)
{
  "itemCount_zero": "لا عناصر",
  "itemCount_one": "عنصر واحد",
  "itemCount_two": "عنصران",
  "itemCount_few": "{{count}} عناصر",
  "itemCount_many": "{{count}} عنصرًا",
  "itemCount_other": "{{count}} عنصر"
}

// Japanese: 1 form (other)
{
  "itemCount_other": "{{count}}個のアイテム"
}
Nekad neierakstiet count === 1 tieši vienskaitļa noteikšanai. Tādas valodas kā franču uzskata 0 par vienskaitli. Krievu, arābu un poļu valodā ir formas, kuru angļu valodā nav. Ļaujiet i18next apstrādāt daudzskaitļa kārtulas.
7

Pievienot valodas pārslēgšanu un noteikšanu

Izveidojiet valodas atlasītāju, kas izsauc i18n.changeLanguage(). Apvienojiet to ar pārlūka valodas noteicēju, lai pirmajā apmeklējumā automātiski noteiktu lietotāja vēlamo valodu un pēc tam saglabātu skaidri norādīto izvēli.

LanguageSwitcher.tsx
import { useTranslation } from 'react-i18next';

const LANGUAGES = [
  { code: 'en', label: 'English' },
  { code: 'de', label: 'Deutsch' },
  { code: 'ja', label: '日本語' },
  { code: 'es', label: 'Español' },
];

function LanguageSwitcher() {
  const { i18n } = useTranslation();

  return (
    <select
      value={i18n.language}
      onChange={(e) => i18n.changeLanguage(e.target.value)}
    >
      {LANGUAGES.map(({ code, label }) => (
        <option key={code} value={code}>{label}</option>
      ))}
    </select>
  );
}
Ja izmantojat SSR (Next.js, Remix), serveris var noteikt citu valodu nekā klients, jo serverim nav pārlūka preferenču. Tas izraisa hidratācijas neatbilstību. Risinājums: nododiet serverī noteikto lokalizāciju klientam kā rekvizītu vai sīkfailu, lai abi atveidotu vienu valodu.
8

Automatizēt tulkošanu

Kad i18n iestatīšana ir pabeigta, tulkojiet lokalizācijas failus ar MI. IDE lūdziet MI asistentam iztulkot avota failu vai CI/CD konveijerā izmantojiet i18n Agent CLI.

Terminal
# In your IDE, ask your AI assistant:
> Translate public/locales/en/translation.json to German, Japanese, and Spanish

✓ de/translation.json created (1.2s)
✓ ja/translation.json created (1.5s)
✓ es/translation.json created (1.1s)

# Or use the CLI in CI/CD:
npx i18n-agent translate public/locales/en/translation.json --lang de,ja,es
Tulkojiet pakāpeniski — pievienojot avota failam jaunas atslēgas, tulkojiet tikai izmaiņas, nevis ģenerējiet visus failus no jauna. Tā saglabāsiet cilvēku pārskatītos tulkojumus.

Automatizēt tulkojumu kvalitāti

Ar i18n-validate pirms izlaišanas atrodiet trūkstošās atslēgas un bojātos vietturus. Kamēr īstie tulkojumi vēl nav gatavi, pārbaudiet UI ar i18n-pseudo pseidotulkojumiem.

Biežākās kļūdas

Tulkojumos redzamas neapstrādātas atslēgas

Iemesli: trūkst I18nextProvider, lietotnes saknē nav importēta i18n konfigurācija, nav ielādēta nosaukumvieta vai tulkojumi joprojām tiek ielādēti asinhroni. Meklējiet norādes pārlūka konsolē ar ieslēgtu debug: true.

Suspense kļūda bez atkāpšanās satura

„A component suspended while responding to synchronous input“ — ietveriet lietotni '&lt;Suspense&gt;' robežā vai i18next init konfigurācijā iestatiet useSuspense: false.

SSR hidratācijas neatbilstība

Serveris atveido vienā lokalizācijā, bet klients hidratē citā. Nodrošiniet, ka abi izmanto vienu lokalizācijas avotu — nododiet to no servera kā rekvizītu un nepaļaujieties tikai uz pārlūka noteikšanu.

Nav tulkošanas atslēgu automātiskās pabeigšanas

Paplašiniet i18next moduli ar savu resursu tipu: declare module 'i18next' '{ interface CustomTypeOptions { resources: typeof resources } }'. Tas nodrošina tipu drošus t() izsaukumus ar automātisko pabeigšanu.

Ieteicamā failu struktūra

Project Structure
my-react-app/
├── public/
│   └── locales/
│       ├── en/
│       │   ├── translation.json    # Default namespace
│       │   ├── common.json         # Shared strings
│       │   └── dashboard.json      # Feature namespace
│       ├── de/
│       │   ├── translation.json
│       │   ├── common.json
│       │   └── dashboard.json
│       └── ja/
│           └── ...
├── src/
│   ├── i18n.ts                     # i18n configuration
│   ├── main.tsx                    # App entry with Provider
│   ├── App.tsx
│   └── components/
│       └── LanguageSwitcher.tsx
└── package.json

Izmēģiniet i18n Agent tūlīt

Nometiet tulkošanas failu šeit

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

vai noklikšķiniet, lai izvēlētos

Mērķa valodas

Reģistrācija nav vajadzīgaTūlītēja tāme

Bieži uzdotie jautājumi