React Internationalization (i18n) con react-intl e Intlayer
Questa guida mostra come integrare Intlayer con react-intl per gestire le traduzioni in un'applicazione React. Dichiari i tuoi contenuti traducibili con Intlayer e poi consuma quei messaggi con react-intl, una popolare libreria dell'ecosistema FormatJS.
Panoramica
- Intlayer ti consente di memorizzare le traduzioni nei file di dichiarazione dei contenuti a livello di componente (JSON, JS, TS, ecc.) all'interno del tuo progetto.
- react-intl fornisce componenti React e hook (come <FormattedMessage> e useIntl()) per visualizzare stringhe localizzate.
Configurando Intlayer per esportare le traduzioni in un formato compatibile con react-intl, puoi automaticamente generare e aggiornare i file di messaggi di cui <IntlProvider> (da react-intl) ha bisogno.
Perché usare Intlayer con react-intl?
Dichiarazioni di contenuto per componente
I file di dichiarazione dei contenuti di Intlayer possono vivere accanto ai tuoi componenti React, evitando traduzioni “orfane” se i componenti vengono spostati o rimossi. Ad esempio:bash.└── src └── components └── MyComponent ├── index.content.ts # Dichiarazione contenuti Intlayer └── index.tsx # Componente React
Traduzioni centralizzate
Ogni file di dichiarazione dei contenuti raccoglie tutte le traduzioni necessarie a un componente. Questo è particolarmente utile nei progetti TypeScript: le traduzioni mancanti possono essere catturate al momento della compilazione.Build e rigenerazione automatiche
Ogni volta che aggiungi o aggiorni le traduzioni, Intlayer rigenera file JSON di messaggio. Puoi quindi passarli a <IntlProvider> di react-intl.
Installazione
In un tipico progetto React, installa i seguenti:
# con npmnpm install intlayer react-intl# con yarnyarn add intlayer react-intl# con pnpmpnpm add intlayer react-intl
Perché questi pacchetti?
- intlayer: CLI core e libreria che scansiona le dichiarazioni di contenuto, le unisce e genera output di dizionario.
- react-intl: La libreria principale di FormatJS che fornisce <IntlProvider>, <FormattedMessage>, useIntl() e altre primitives di internazionalizzazione.
Se non hai già installato React, avrai bisogno anche di esso (react e react-dom).
Configurare Intlayer per esportare i messaggi react-intl
Nella radice del tuo progetto, crea intlayer.config.ts (o .js, .mjs, .cjs) in questo modo:
import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = { internationalization: { // Aggiungi quanti più locali desideri locales: [Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH], defaultLocale: Locales.ENGLISH, }, content: { // Indica a Intlayer di generare file di messaggi per react-intl dictionaryOutput: ["react-intl"], // La directory in cui Intlayer scriverà i tuoi file JSON di messaggi reactIntlMessagesDir: "./react-intl/messages", },};export default config;
Nota: Per altri tipi di file (.mjs, .cjs, .js), consulta la documentazione di Intlayer per i dettagli sull'uso.
Creazione delle dichiarazioni di contenuto di Intlayer
Intlayer scansiona il tuo codice sorgente (per impostazione predefinita, sotto ./src) per file che corrispondono a *.content.{ts,tsx,js,jsx,mjs,cjs,json}.
Ecco un esempio in TypeScript:
import { t, type DeclarationContent } from "intlayer";const content = { // "chiave" diventa la chiave di messaggio di primo livello nel tuo file JSON react-intl key: "my-component", content: { // Ogni chiamata a t() dichiara un campo traducibile helloWorld: t({ en: "Hello World", fr: "Bonjour le monde", es: "Hola Mundo", }), description: t({ en: "This is a description", fr: "Ceci est une description", es: "Esta es una descripción", }), },} satisfies DeclarationContent;export default content;
Se preferisci JSON o diversi tipi di JS (.cjs, .mjs), la struttura è essenzialmente la stessa—vedi documentazione di Intlayer sulla dichiarazione dei contenuti.
Costruzione dei messaggi react-intl
Per generare i file JSON di messaggi effettivi per react-intl, esegui:
# con npmnpx intlayer build# con yarnyarn intlayer build# con pnpmpnpm intlayer build
Questo scansiona tutti i file *.content.*, li compila e scrive i risultati nella directory specificata nel tuo intlayer.config.ts — in questo esempio, ./react-intl/messages.
Un output tipico potrebbe apparire così:
.└── react-intl └── messages ├── en.json ├── fr.json └── es.json
Ogni file è un oggetto JSON i cui chiavi di primo livello corrispondono a ciascuna content.key dalle tue dichiarazioni. Le sotto-chiavi (come helloWorld) riflettono le traduzioni dichiarate all'interno di quell'elemento di contenuto.
Ad esempio, il en.json potrebbe apparire così:
{ "helloWorld": "Hello World", "description": "This is a description"}
Inizializzare react-intl nella tua app React
1. Carica i messaggi generati
Dove configuri il componente radice della tua app (ad esempio, src/main.tsx o src/index.tsx), dovrai:
- Importare i file di messaggi generati (staticamente o dinamicamente).
- Fornirli a <IntlProvider> da react-intl.
Un approccio semplice è importare staticamente:
import React from "react";import ReactDOM from "react-dom/client";import { IntlProvider } from "react-intl";import App from "./App";// Importa i file JSON dall'output della build.// In alternativa, puoi importare dinamicamente in base alla lingua scelta dall'utente.import en from "../react-intl/messages/en.json";import fr from "../react-intl/messages/fr.json";import es from "../react-intl/messages/es.json";// Se hai un meccanismo per rilevare la lingua dell'utente, impostalo qui.// Per semplicità, scegliamo l'inglese.const locale = "en";// Raccogli i messaggi in un oggetto (o scegli in modo dinamico)const messagesRecord: Record<string, Record<string, any>> = { en, fr, es,};ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render( <React.StrictMode> <IntlProvider locale={locale} messages={messagesRecord[locale]}> <App /> </IntlProvider> </React.StrictMode>);
Suggerimento: Per progetti reali, potresti:
- Caricare dinamicamente i messaggi JSON a runtime.
- Utilizzare rilevamenti di locale basati su ambiente, browser o account utente.
2. Usa <FormattedMessage> o useIntl()
Una volta che i tuoi messaggi sono stati caricati in <IntlProvider>, qualsiasi componente figlio può utilizzare react-intl per accedere a stringhe localizzate. Ci sono due approcci principali:
- Componente <FormattedMessage>
- Hook useIntl()
Utilizzo delle traduzioni nei componenti React
Approccio A: <FormattedMessage>
Per un utilizzo rapido in linea:
import React from "react";import { FormattedMessage } from "react-intl";export default function MyComponent() { return ( <div> <h1> {/* “my-component.helloWorld” fa riferimento alla chiave da en.json, fr.json, ecc. */} <FormattedMessage id="my-component.helloWorld" /> </h1> <p> <FormattedMessage id="my-component.description" /> </p> </div> );}
La prop id in <FormattedMessage> deve corrispondere alla chiave di primo livello (my-component) più eventuali sotto-chiavi (helloWorld).
Approccio B: useIntl()
Per un utilizzo più dinamico:
import React from "react";import { useIntl } from "react-intl";export default function MyComponent() { const intl = useIntl(); return ( <div> <h1>{intl.formatMessage({ id: "my-component.helloWorld" })}</h1> <p>{intl.formatMessage({ id: "my-component.description" })}</p> </div> );}
Entrambi gli approcci sono validi: scegli quello che meglio si adatta alla tua app.
Aggiornamento o aggiunta di nuove traduzioni
- Aggiungi o modifica contenuti in qualsiasi file *.content.*.
- Riesegui intlayer build per rigenerare i file JSON sotto ./react-intl/messages.
- React (e react-intl) rileveranno gli aggiornamenti la prossima volta che ricompili o ricarichi la tua applicazione.
Integrazione TypeScript (Opzionale)
Se stai usando TypeScript, Intlayer può generare definizioni di tipo per le tue traduzioni.
- Assicurati che tsconfig.json includa la tua cartella types (o qualsiasi altra cartella di output generata da Intlayer) nell'array "include".
{ "compilerOptions": { // ... }, "include": ["src", "types"],}
I tipi generati possono aiutare a rilevare traduzioni mancanti o chiavi non valide nei tuoi componenti React al momento della compilazione.
Configurazione Git
È comune escludere gli artefatti di build interni di Intlayer dal controllo versione. Nel tuo .gitignore, aggiungi:
# Ignora gli artefatti di build di intlayer.intlayerreact-intl
A seconda del tuo flusso di lavoro, potresti anche voler ignorare o impegnare i dizionari finali in ./react-intl/messages. Se la tua pipeline CI/CD li rigenera, puoi ignorarli in sicurezza; altrimenti, impegnali se hai bisogno di loro per le distribuzioni in produzione.
Se hai un’idea per migliorare questa blogumentazione, non esitare a contribuire inviando una pull request su GitHub.
Collegamento GitHub al blog