Skip to main content

Οδηγός react-intl: Ρύθμιση διεθνοποίησης React

Ρυθμίστε το react-intl του FormatJS στην εφαρμογή React με IntlProvider, FormattedMessage, useIntl, μορφή μηνυμάτων ICU και αυτοματοποιημένες μεταφράσεις.

Χρησιμοποιείτε react-i18next; Δείτε τον οδηγό μας για το react-i18next

1

Εγκαταστήστε το react-intl

Το react-intl αποτελεί μέρος του έργου FormatJS. Παρέχει στοιχεία και hooks του React για τη μορφοποίηση συμβολοσειρών, αριθμών, ημερομηνιών και πληθυντικών μέσω του προτύπου ICU MessageFormat.

Το react-intl δεν έχει εξαρτήσεις κατά την εκτέλεση πέρα από το React. Χρησιμοποιεί το ενσωματωμένο API Intl του προγράμματος περιήγησης για τη μορφοποίηση αριθμών και ημερομηνιών και περιλαμβάνει τον δικό του parser ICU MessageFormat για πληθυντικούς, select και εμπλουτισμένο κείμενο.
Terminal
npm install react-intl
2

Ρυθμίστε το IntlProvider

Περιβάλετε την εφαρμογή σας με το IntlProvider στη ρίζα. Μεταβιβάστε την ενεργή τοπική ρύθμιση και ένα επίπεδο αντικείμενο messages. Κάθε στοιχείο που βρίσκεται χαμηλότερα μπορεί έπειτα να αποκτά πρόσβαση στις μεταφράσεις μέσω του FormattedMessage ή του 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 απαιτεί ένα επίπεδο αντικείμενο ζευγών κλειδιού-τιμής για τα μηνύματα (π.χ. { "app.greeting": "Hello" }). Τα ένθετα JSON πρέπει να μετατραπούν σε επίπεδη μορφή πριν μεταβιβαστούν στο IntlProvider. Εναλλακτικά, χρησιμοποιήστε ένα εργαλείο όπως το flat για τη μετατροπή ένθετων δομών.

Αρχεία μηνυμάτων

Δημιουργήστε ένα αρχείο JSON ανά τοπική ρύθμιση. Το react-intl χρησιμοποιεί εγγενώς τη σύνταξη ICU MessageFormat — οι πληθυντικοί, το select και οι μεταβλητές εκφράζονται όλα ενσωματωμένα στις συμβολοσειρές μηνυμάτων.

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"
}
Χρησιμοποιήστε αναγνωριστικά χωρισμένα με τελείες, όπως "nav.home", για οργάνωση. Σε αντίθεση με το react-i18next, το react-intl αναμένει ένα επίπεδο αντικείμενο messages — μετατρέπετε τα κλειδιά και όχι τη δομή σε επίπεδη μορφή.
3

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

Το react-intl σάς παρέχει δύο βασικά API: το στοιχείο FormattedMessage για απόδοση μεταφρασμένου JSX και το hook useIntl για προγραμματιστική πρόσβαση (placeholders, ετικέτες aria και προγραμματιστική μορφοποίηση).

Στοιχείο FormattedMessage

Χρησιμοποιήστε το FormattedMessage για δηλωτικές μεταφράσεις σε JSX. Μεταβιβάστε το αναγνωριστικό μηνύματος και τυχόν τιμές παρεμβολής. Αποδίδει απευθείας τη μεταφρασμένη συμβολοσειρά.

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

Το hook useIntl

Χρησιμοποιήστε το useIntl() όταν χρειάζεστε τη μεταφρασμένη συμβολοσειρά ως απλή τιμή — για placeholders πεδίων εισαγωγής, aria-labels, document.title ή όταν μεταβιβάζετε συμβολοσειρές σε API εκτός React. Παρέχει επίσης τα formatNumber, formatDate και 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>
  );
}

Εμπλουτισμένο κείμενο (HTML στις μεταφράσεις)

Ενσωματώστε JSX στις μεταφράσεις χρησιμοποιώντας ετικέτες τύπου XML στις συμβολοσειρές μηνυμάτων. Μεταβιβάστε χειριστές ετικετών μέσω του prop values για να αποδώσετε συνδέσμους, έντονο κείμενο ή οποιοδήποτε στοιχείο React μέσα σε ένα μεταφρασμένο μήνυμα.

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>,
      }}
    />
  );
}
Το FormattedMessage αποδίδει από προεπιλογή ένα React Fragment. Αν χρειάζεστε συγκεκριμένο στοιχείο περιτύλιξης, μεταβιβάστε το prop textComponent στο IntlProvider ή περιβάλετε το FormattedMessage με δικό σας στοιχείο.

Εξαγωγή μηνυμάτων με το @formatjs/cli

Το FormatJS παρέχει ένα CLI για την αυτόματη εξαγωγή αναγνωριστικών μηνυμάτων από τον πηγαίο κώδικα σε αρχείο JSON. Έτσι το αρχείο μηνυμάτων παραμένει συγχρονισμένο με τα στοιχεία σας χωρίς χειροκίνητη διαχείριση.

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

Πληθυντικοί και ICU select

Το react-intl χρησιμοποιεί εγγενώς ICU MessageFormat. Οι πληθυντικοί, το select βάσει γένους και η ένθετη μορφοποίηση εκφράζονται απευθείας στις συμβολοσειρές μηνυμάτων — δεν απαιτούνται συμβάσεις επιθημάτων ή ξεχωριστά κλειδιά.

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}個の商品があります"
}
Μην ενσωματώνετε ποτέ τη λογική πληθυντικού στο JavaScript. Γλώσσες όπως τα Αραβικά έχουν 6 μορφές πληθυντικού, τα Γαλλικά θεωρούν το 0 ενικό και τα Ιαπωνικά δεν διακρίνουν τον πληθυντικό. Αφήστε το ICU MessageFormat να διαχειριστεί τους κανόνες — απλώς μεταβιβάστε την τιμή count.

ICU select για γένος και ρόλους

Χρησιμοποιήστε τη σύνταξη ICU select για μεταφράσεις που εξαρτώνται από το συγκείμενο, όπως το γένος, οι ρόλοι χρηστών ή οι τιμές κατάστασης. Η έκφραση select επιλέγει τη σωστή παραλλαγή βάσει της παρεχόμενης τιμής.

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

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

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

Συνηθισμένες παγίδες

Υπερβολική εξάρτηση από το defaultMessage

Το defaultMessage είναι εφεδρική τιμή για την ανάπτυξη και όχι στρατηγική μετάφρασης. Αν χρησιμοποιείτε defaultMessage για όλες τις συμβολοσειρές, η έξοδος εξαγωγής μηνυμάτων θα περιέχει το αγγλικό κείμενο, αλλά οι μεταφραστές μπορεί να παραβλέψουν νέα κλειδιά. Εξάγετε και συντηρείτε πάντα ένα πλήρες αρχείο γλώσσας προέλευσης.

Ένθετα αντικείμενα αντί για επίπεδα κλειδιά

Το IntlProvider αναμένει ένα επίπεδο Record&lt;string, string&gt; για τα μηνύματα. Αν μεταβιβάσετε ένθετο JSON όπως { nav: { home: "Home" } }, το react-intl δεν θα βρει το κλειδί "nav.home". Μετατρέψτε τα μηνύματα σε επίπεδη μορφή πριν τα μεταβιβάσετε ή χρησιμοποιήστε μια βιβλιοθήκη όπως το flat.

Το IntlProvider προκαλεί επαναποδόσεις

Αν δημιουργείτε το αντικείμενο messages απευθείας μέσα στη συνάρτηση render, το IntlProvider λαμβάνει νέα αναφορά αντικειμένου σε κάθε απόδοση, με αποτέλεσμα να επαναποδίδονται όλοι οι καταναλωτές. Αποθηκεύστε προσωρινά το messages με useMemo ή ορίστε το εκτός του στοιχείου.

Απουσία IntlProvider στις δοκιμές

Τα στοιχεία που χρησιμοποιούν FormattedMessage ή useIntl δημιουργούν εξαίρεση αν αποδοθούν χωρίς πρόγονο IntlProvider. Στις δοκιμές, περιβάλετε το στοιχείο σας με IntlProvider, με locale="en" και ένα κενό ή ελάχιστο αντικείμενο messages.

Συνιστώμενη δομή αρχείων

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

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

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

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

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

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

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

Εναλλακτική τοπική ρύθμιση με το react-intl-locale-chain

Όταν λείπει ένα κλειδί μετάφρασης από μια περιφερειακή τοπική ρύθμιση όπως η pt-BR, το react-intl μεταβαίνει απευθείας στην προεπιλεγμένη τοπική ρύθμιση αντί να ελέγξει πρώτα τη γονική 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>

Δείτε τον Οδηγό εναλλακτικών τοπικών ρυθμίσεων για τον πλήρη κατάλογο των υποστηριζόμενων framework και των 75 ενσωματωμένων αλυσίδων. Learn more →

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