Skip to main content

Den kompletta guiden till internationalisering i React

Från ett språk till flera: konfigurera i18n i din React-app och automatisera sedan översättningarna med AI.

1

Installera paket

Du behöver tre paket: react-i18next (React-bindningarna), i18next (kärnbiblioteket) och eventuellt i18next-browser-languagedetector för automatisk identifiering av språkvariant.

react-i18next tillhandahåller React-hooks och komponenter. i18next är kärnmotorn som hanterar inläsning av översättningar, interpolering och pluralisering. Insticksprogrammet för språkidentifiering läser automatiskt webbläsarens språkinställning.
Terminal
npm install react-i18next i18next i18next-browser-languagedetector i18next-http-backend
2

Konfigurera i18n-instansen

Skapa en i18n-konfigurationsfil som initierar i18next med ditt standardspråk, dina översättningsresurser och din kedja av insticksprogram. Filen måste importeras vid appens startpunkt innan någon komponent renderas.

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" — felet innebär att du glömde anropa i18n.use(initReactI18next) före i18n.init(). Anropet .use() måste komma före .init().
3

Omslut appen med I18nextProvider

Importera din i18n-konfigurationsfil i appens rot och omslut komponentträdet med I18nextProvider. Utan detta returnerar useTranslation() råa nycklar i stället för översatt text.

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>
);
Om översättningarna visar råa nycklar som "welcome" i stället för "Välkommen till vår app" beror det oftast på att I18nextProvider saknas eller att i18n-konfigurationsfilen inte har importerats.
4

Skapa översättningsfiler

Skapa en JSON-fil per språk. Använd nästlade nycklar för att organisera strängar efter funktion eller sida. Behåll källspråket (vanligtvis engelska) som enda källa.

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"
  }
}
Namnge nycklar efter vad de beskriver, inte var de visas: "cart.itemCount" är bättre än "homepageCartLabel". Nycklarna ska fungera även efter att gränssnittet har gjorts om.
5

Använd översättningar i komponenter

Anropa useTranslation() i valfri komponent för att hämta funktionen t(). Använd den för enkla strängar, interpolerade variabler och översättningar med inbäddad JSX via komponenten 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" />
    }} />
  );
}
Dynamiska nycklar som t(`error.$'{code}'`) fungerar vid körning, men kan inte extraheras statiskt av verktyg som i18next-scanner. Om du använder extraheringsverktyg ska du ange dynamiska nycklar uttryckligen eller använda en kommentarsmarkör.
6

Hantera pluralformer och variabler

i18next hanterar pluralformer med CLDR-regler, inte bara singular och plural. Arabiska har 6 former (zero, one, two, few, many, other). Japanska har 1 (other). Definiera alla former som behövs i översättningsfilerna så väljer i18next automatiskt rätt form.

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}}個のアイテム"
}
Hårdkoda aldrig count === 1 för att identifiera singular. Språk som franska behandlar 0 som singular. Ryska, arabiska och polska har former som saknas i engelskan. Låt i18next hantera pluralreglerna.
7

Lägg till språkbyte och språkidentifiering

Skapa en språkväljare som anropar i18n.changeLanguage(). Kombinera den med webbläsarens språkidentifiering för att automatiskt identifiera användarens önskade språk vid det första besöket och spara sedan användarens uttryckliga val.

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>
  );
}
Om du använder SSR (Next.js, Remix) kan servern identifiera ett annat språk än klienten eftersom servern saknar webbläsarinställningar. Det orsakar en hydreringskonflikt. Lösning: skicka den identifierade språkvarianten från servern till klienten som en prop eller cookie så att båda renderar samma språk.
8

Automatisera översättningar

När din i18n-konfiguration är klar kan du översätta språkfilerna med AI. Be AI-assistenten i din IDE att översätta källfilen eller använd i18n Agent CLI i din CI/CD-pipeline.

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
Översätt stegvis. När du lägger till nya nycklar i källfilen översätter du bara ändringarna i stället för att skapa om alla filer. Då bevaras översättningar som har granskats av människor.

Automatisera översättningskvaliteten

Upptäck saknade nycklar och trasiga platshållare före lansering med i18n-validate. Testa gränssnittet med testöversättningar via i18n-pseudo innan de riktiga översättningarna är klara.

Vanliga fallgropar

Översättningar visar råa nycklar

Möjliga orsaker: I18nextProvider saknas, i18n-konfigurationen har inte importerats i appens rot, namnrymden har inte lästs in eller översättningarna läses fortfarande in asynkront. Sök efter ledtrådar i webbläsarkonsolen med debug: true.

Suspense-fel utan reservinnehåll

"A component suspended while responding to synchronous input" — lägg till en '&lt;Suspense&gt;'-gräns runt appen eller ange useSuspense: false i i18next-konfigurationen.

Hydreringskonflikt med SSR

Servern renderar med en språkvariant och klienten hydrerar med en annan. Se till att båda använder samma källa för språkvarianten. Skicka den som en prop från servern och förlita dig inte enbart på webbläsarens identifiering.

Ingen automatisk komplettering av översättningsnycklar

Utöka i18next-modulen med din resurstyp: declare module 'i18next' '{ interface CustomTypeOptions { resources: typeof resources } }'. Då får du typsäkra anrop till t() med automatisk komplettering.

Rekommenderad filstruktur

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

Prova i18n Agent nu

Släpp din översättningsfil här

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

eller klicka för att välja en fil

Målspråk

Ingen registrering krävsPrisuppskattning direkt

Vanliga frågor