Skip to main content

Potpuni vodič za internacionalizaciju u Reactu

Od nule do višejezičnosti: postavite i18n u svojoj React aplikaciji, a zatim automatizirajte prevođenje pomoću AI.

1

Instalirajte pakete

Potrebna su Vam tri paketa: react-i18next (povezivanja za React), i18next (temeljna biblioteka) te, po želji, i18next-browser-languagedetector za automatsko otkrivanje lokalne postavke.

react-i18next pruža React hookove i komponente. i18next je temeljni mehanizam koji upravlja učitavanjem prijevoda, interpolacijom i oblicima množine. Dodatak za otkrivanje jezika automatski očitava jezičnu postavku preglednika.
Terminal
npm install react-i18next i18next i18next-browser-languagedetector i18next-http-backend
2

Konfigurirajte instancu i18n

Izradite konfiguracijsku datoteku i18n koja inicijalizira i18next sa zadanim jezikom, resursima prijevoda i lancem dodataka. Tu datoteku morate uvesti na ulaznoj točki aplikacije prije prikaza bilo koje komponente.

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" — ova pogreška znači da ste zaboravili pozvati i18n.use(initReactI18next) prije i18n.init(). Poziv .use() mora prethoditi pozivu .init().
3

Omotajte aplikaciju komponentom I18nextProvider

Uvezite konfiguracijsku datoteku i18n u korijenu aplikacije i omotajte stablo komponenti komponentom I18nextProvider. Bez toga useTranslation() vraća neobrađene ključeve umjesto prevedenog teksta.

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>
);
Ako se umjesto prijevoda prikazuju neobrađeni ključevi poput „welcome" umjesto „Welcome to our app", najčešći je uzrok komponenta I18nextProvider koja nedostaje ili konfiguracijska datoteka i18n koja nije uvezena.
4

Napravite datoteke prijevoda

Izradite po jednu JSON datoteku za svaki jezik. Ugniježđenim ključevima organizirajte nizove prema značajci ili stranici. Izvorni jezik (obično engleski) zadržite kao jedini izvor istine.

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"
  }
}
Ključeve imenujte prema onome što opisuju, a ne prema mjestu na kojem se pojavljuju: „cart.itemCount" bolje je od „homepageCartLabel". Ključevi trebaju opstati i nakon redizajna korisničkog sučelja.
5

Upotrebljavajte prijevode u komponentama

Pozovite useTranslation() u bilo kojoj komponenti kako biste dobili funkciju t(). Upotrebljavajte je za jednostavne nizove, interpolirane varijable i prijevode s ugrađenim JSX sadržajem putem komponente 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" />
    }} />
  );
}
Dinamički ključevi poput t(`error.$'{code}'`) rade tijekom izvođenja, ali ih alati poput i18next-scanner ne mogu statički izdvojiti. Ako upotrebljavate alate za izdvajanje, izričito navedite dinamičke ključeve ili dodajte napomenu u komentaru.
6

Obradite množinu i varijable

i18next obrađuje oblike množine prema pravilima CLDR-a — ne samo jedninu i množinu. Arapski ima šest oblika (zero, one, two, few, many, other), a japanski jedan (other). Definirajte sve potrebne oblike u datotekama prijevoda, a i18next će automatski odabrati odgovarajući.

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}}個のアイテム"
}
Nikada nemojte u kodu upotrebljavati count === 1 za prepoznavanje jednine. Jezici poput francuskog smatraju 0 jedninom. Ruski, arapski i poljski imaju oblike koji ne postoje u engleskom. Prepustite i18nextu primjenu pravila množine.
7

Dodajte promjenu i otkrivanje jezika

Izradite izbornik jezika koji poziva i18n.changeLanguage(). Povežite ga s dodatkom za otkrivanje jezika preglednika kako biste pri prvom posjetu automatski otkrili željeni jezik korisnika, a zatim sačuvali njegov izričiti odabir.

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>
  );
}
Ako upotrebljavate SSR (Next.js, Remix), poslužitelj može otkriti jezik različit od klijenta jer nema pristup postavkama preglednika. To uzrokuje nepodudaranje hidracije. Rješenje: otkrivenu lokalnu postavku proslijedite s poslužitelja klijentu kao prop ili kolačić kako bi oba prikazala isti jezik.
8

Automatizirajte prevođenje

Nakon dovršetka postavljanja i18n prevedite datoteke lokalnih postavki pomoću AI. U IDE-u zatražite od AI pomoćnika da prevede izvornu datoteku ili upotrijebite i18n Agent CLI u svojem CI/CD pipelineu.

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
Prevodite postupno — kada izvornoj datoteci dodate nove ključeve, prevedite samo razliku umjesto ponovnog generiranja svih datoteka. Tako ćete sačuvati prijevode koje su pregledali ljudi.

Automatizirajte kvalitetu prijevoda

Prije objave otkrijte ključeve koji nedostaju i neispravna rezervirana mjesta pomoću i18n-validate. Testirajte korisničko sučelje lažnim prijevodima pomoću i18n-pseudo prije nego što stignu stvarni prijevodi.

Uobičajene zamke

Prijevodi prikazuju neobrađene ključeve

Uzroci: nedostaje I18nextProvider, konfiguracija i18n nije uvezena u korijenu aplikacije, prostor imena nije učitan ili se prijevodi još učitavaju asinkrono. Potražite naznake u konzoli preglednika uz debug: true.

Pogreška značajke Suspense bez pričuvnog prikaza

„A component suspended while responding to synchronous input" — dodajte granicu '&lt;Suspense&gt;' oko aplikacije ili u konfiguraciji init za i18next postavite useSuspense: false.

Neusklađenost SSR hidratacije

Poslužitelj prikazuje jednu lokalnu postavku, a klijent hidrira drugu. Osigurajte da oba upotrebljavaju isti izvor lokalne postavke — proslijedite je s poslužitelja kao prop i nemojte se oslanjati samo na otkrivanje jezika preglednika.

Bez automatskog dovršavanja ključeva prijevoda

Proširite modul i18next svojim tipom resursa: declare module 'i18next' '{ interface CustomTypeOptions { resources: typeof resources } }'. Time pozivi t() dobivaju sigurnost tipova i automatsko dovršavanje.

Preporučena struktura datoteka

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

Isprobajte i18n Agent odmah

Povucite datoteku za prijevod ovdje

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

ili kliknite za odabir

Ciljni jezici

Registracija nije potrebnaProcjena odmah

Česta pitanja