Skip to main content

Ο πλήρης οδηγός διεθνοποίησης στο React

Από το μηδέν σε μια πολύγλωσση εφαρμογή: ρυθμίστε το i18n στην εφαρμογή React και έπειτα αυτοματοποιήστε τις μεταφράσεις με AI.

1

Εγκαταστήστε τα πακέτα

Χρειάζεστε τρία πακέτα: το react-i18next (τα bindings του React), το i18next (τη βασική βιβλιοθήκη) και, προαιρετικά, το i18next-browser-languagedetector για αυτόματη ανίχνευση της τοπικής ρύθμισης.

Το react-i18next παρέχει hooks και components για το React. Το i18next είναι ο βασικός μηχανισμός που διαχειρίζεται τη φόρτωση μεταφράσεων, την παρεμβολή και τον σχηματισμό πληθυντικού. Το plugin ανίχνευσης γλώσσας διαβάζει αυτόματα τη γλωσσική προτίμηση του προγράμματος περιήγησης.
Terminal
npm install react-i18next i18next i18next-browser-languagedetector i18next-http-backend
2

Ρυθμίστε το instance του i18n

Δημιουργήστε ένα αρχείο ρυθμίσεων i18n που αρχικοποιεί το i18next με την προεπιλεγμένη γλώσσα, τους πόρους μετάφρασης και την αλυσίδα των plugin. Αυτό το αρχείο πρέπει να εισάγεται στο σημείο εισόδου της εφαρμογής σας προτού αποδοθεί οποιοδήποτε component.

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" — αυτό το σφάλμα σημαίνει ότι ξεχάσατε να καλέσετε το i18n.use(initReactI18next) πριν από το i18n.init(). Η κλήση .use() πρέπει να προηγείται της .init().
3

Περιβάλετε την εφαρμογή σας με I18nextProvider

Εισαγάγετε το αρχείο ρυθμίσεων i18n στη ρίζα της εφαρμογής και περιβάλετε το δέντρο των component με I18nextProvider. Χωρίς αυτό, η useTranslation() επιστρέφει ανεπεξέργαστα κλειδιά αντί για μεταφρασμένο κείμενο.

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>
);
Αν οι μεταφράσεις εμφανίζουν ανεπεξέργαστα κλειδιά όπως "welcome" αντί για "Welcome to our app", η συνηθέστερη αιτία είναι ότι λείπει το I18nextProvider ή ότι δεν έχει εισαχθεί το αρχείο ρυθμίσεων i18n.
4

Δημιουργήστε αρχεία μετάφρασης

Δημιουργήστε ένα αρχείο JSON ανά γλώσσα. Χρησιμοποιήστε ένθετα κλειδιά για να οργανώσετε τα κείμενα ανά λειτουργία ή σελίδα. Διατηρήστε τη γλώσσα του πρωτοτύπου (συνήθως τα Αγγλικά) ως τη μοναδική αξιόπιστη πηγή.

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"
  }
}
Ονομάστε τα κλειδιά σύμφωνα με αυτό που περιγράφουν και όχι με το σημείο όπου εμφανίζονται: το "cart.itemCount" είναι προτιμότερο από το "homepageCartLabel". Τα κλειδιά πρέπει να παραμένουν έγκυρα μετά από επανασχεδιασμούς του UI.
5

Χρησιμοποιήστε μεταφράσεις στα component

Καλέστε τη useTranslation() σε οποιοδήποτε component για να λάβετε τη συνάρτηση t(). Χρησιμοποιήστε την για απλά κείμενα, μεταβλητές με παρεμβολή και μεταφράσεις που ενσωματώνουν JSX μέσω του component 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" />
    }} />
  );
}
Τα δυναμικά κλειδιά όπως t(`error.$'{code}'`) λειτουργούν κατά την εκτέλεση, αλλά εργαλεία όπως το i18next-scanner δεν μπορούν να τα εξαγάγουν στατικά. Αν χρησιμοποιείτε εργαλεία εξαγωγής, δηλώστε ρητά τα δυναμικά κλειδιά ή χρησιμοποιήστε ένα σχόλιο-υπόδειξη.
6

Χειριστείτε πληθυντικούς και μεταβλητές

Το i18next χειρίζεται τους πληθυντικούς βάσει των κανόνων CLDR — όχι μόνο με ενικό και πληθυντικό. Τα Αραβικά έχουν 6 μορφές (zero, one, two, few, many, other). Τα Ιαπωνικά έχουν 1 (other). Ορίστε στα αρχεία μετάφρασης όλες τις απαιτούμενες μορφές και το i18next θα επιλέγει αυτόματα τη σωστή.

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}}個のアイテム"
}
Μην ενσωματώνετε ποτέ στον κώδικα τον έλεγχο count === 1 για την ανίχνευση του ενικού. Γλώσσες όπως τα Γαλλικά αντιμετωπίζουν το 0 ως ενικό. Τα Ρωσικά, τα Αραβικά και τα Πολωνικά έχουν μορφές που δεν υπάρχουν στα Αγγλικά. Αφήστε το i18next να χειριστεί τους κανόνες πληθυντικού.
7

Προσθέστε εναλλαγή και ανίχνευση γλώσσας

Δημιουργήστε έναν επιλογέα γλώσσας που καλεί την i18n.changeLanguage(). Συνδυάστε τον με την ανίχνευση γλώσσας του προγράμματος περιήγησης, ώστε να εντοπίζεται αυτόματα η προτιμώμενη γλώσσα του χρήστη κατά την πρώτη επίσκεψη και κατόπιν να αποθηκεύεται η ρητή επιλογή του.

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>
  );
}
Αν χρησιμοποιείτε SSR (Next.js, Remix), ο διακομιστής ενδέχεται να ανιχνεύσει διαφορετική γλώσσα από τον client (ο διακομιστής δεν έχει πρόσβαση στις προτιμήσεις του προγράμματος περιήγησης). Αυτό προκαλεί ασυμφωνία hydration. Λύση: μεταβιβάστε την τοπική ρύθμιση που ανιχνεύτηκε από τον διακομιστή στον client ως prop ή cookie, ώστε και οι δύο να αποδίδουν την ίδια γλώσσα.
8

Αυτοματοποιήστε τις μεταφράσεις

Αφού ολοκληρώσετε τη ρύθμιση του i18n, μεταφράστε τα αρχεία γλωσσών με AI. Στο IDE σας, ζητήστε από τον βοηθό AI να μεταφράσει το αρχείο προέλευσης ή χρησιμοποιήστε το CLI του i18n Agent στο pipeline CI/CD.

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
Μεταφράζετε σταδιακά — όταν προσθέτετε νέα κλειδιά στο αρχείο προέλευσης, μεταφράζετε μόνο το diff αντί να δημιουργείτε ξανά όλα τα αρχεία. Έτσι διατηρούνται οι μεταφράσεις που έχουν ήδη ελεγχθεί από άνθρωπο.

Αυτοματοποιήστε τον έλεγχο ποιότητας των μεταφράσεων

Εντοπίστε κλειδιά που λείπουν και κατεστραμμένα placeholder πριν φτάσουν στην παραγωγή με το i18n-validate. Δοκιμάστε το UI σας με ψευδομεταφράσεις μέσω του i18n-pseudo πριν καταφθάσουν οι πραγματικές μεταφράσεις.

Συνήθεις παγίδες

Οι μεταφράσεις εμφανίζουν ανεπεξέργαστα κλειδιά

Αιτίες: λείπει το I18nextProvider, οι ρυθμίσεις i18n δεν έχουν εισαχθεί στη ρίζα της εφαρμογής, το namespace δεν έχει φορτωθεί ή οι μεταφράσεις εξακολουθούν να φορτώνονται ασύγχρονα. Αναζητήστε ενδείξεις στην κονσόλα του προγράμματος περιήγησης με debug: true.

Σφάλμα Suspense χωρίς fallback

"A component suspended while responding to synchronous input" — προσθέστε ένα όριο '&lt;Suspense&gt;' γύρω από την εφαρμογή σας ή ορίστε useSuspense: false στις ρυθμίσεις αρχικοποίησης του i18next.

Ασυμφωνία hydration στο SSR

Ο διακομιστής αποδίδει το περιεχόμενο σε μία τοπική ρύθμιση και ο client πραγματοποιεί hydration σε άλλη. Βεβαιωθείτε ότι και οι δύο χρησιμοποιούν την ίδια πηγή τοπικής ρύθμισης — μεταβιβάστε την ως prop από τον διακομιστή και μη βασίζεστε μόνο στην ανίχνευση του προγράμματος περιήγησης.

Δεν υπάρχει αυτόματη συμπλήρωση για τα κλειδιά μετάφρασης

Επεκτείνετε το module i18next με τον τύπο του πόρου σας: declare module 'i18next' '{ interface CustomTypeOptions { resources: typeof resources } }'. Έτσι αποκτάτε κλήσεις t() με ασφάλεια τύπων και αυτόματη συμπλήρωση.

Προτεινόμενη δομή αρχείων

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

Δοκιμάστε τώρα το i18n Agent

Αφήστε εδώ το αρχείο μετάφρασής σας

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

ή κάντε κλικ για να επιλέξετε αρχείο

Γλώσσες-στόχοι

Δεν απαιτείται εγγραφήΆμεση εκτίμηση

Συχνές ερωτήσεις