Pose una domanda e ottieni un riassunto del documento facendo riferimento a questa pagina e al provider AI di tua scelta
Cronologia delle versioni
- "Versione iniziale"v9.5.1026/09/2026
Il contenuto di questa pagina è stato tradotto con un'IA.
Vedi l'ultima versione del contenuto originale in ingleseSe hai un’idea per migliorare questa documentazione, non esitare a contribuire inviando una pull request su GitHub.
Collegamento GitHub alla documentazioneCopia il Markdown del documento nella porta-documenti
Come internazionalizzare la tua applicazione TanStack Start usando Lingui nel 2026
Indice
Cos'è Lingui?
Lingui è una libreria di i18n costruita attorno a macro ed estrazione dei messaggi. Scrivi il testo sorgente direttamente nei tuoi componenti ( t`Hello` , <Trans>Hello</Trans>), lingui extract raccoglie ogni messaggio nei cataloghi (file PO per impostazione predefinita), i traduttori li compilano e il plugin Vite li compila in JavaScript compatto. I messaggi utilizzano ICU MessageFormat, quindi i plurali e i select sono supportati.
TanStack Start non include un livello di i18n integrato, quindi questa guida integra Lingui da zero:
- Macro compilate da Babel tramite
@rolldown/plugin-babel(necessario con@vitejs/plugin-reactv6 e Vite 8). - Routing delle lingue con un segmento opzionale
{-$locale}(/about,/fr/about). - Un catalogo per lingua, caricato su richiesta, e un'istanza
I18nper ogni render in modo che le richieste SSR simultanee non condividano mai una lingua. - SEO multilingue completo:
<title>e descrizione tradotti, URL canonico,hreflangconx-default, impostazioni locali Open Graph, JSON-LD, sitemap,robots.txt, pre-rendering e pagine 404 localizzate.
Cerchi un altro stack? Consulta la guida a TanStack Start + use-intl, la guida a TanStack Start + Paraglide o la guida a TanStack Start + Intlayer.
Usi Next.js? Consulta la guida a Next.js + Lingui. Vuoi confrontare le librerie? Leggi Lingui vs Intlayer.
Cosa dice il benchmark su Lingui in TanStack Start
Il benchmark i18n esegue la stessa applicazione TanStack Start con 10 pagine e 10 lingue con tutte le principali librerie e misura ciò che il browser scarica effettivamente.
Caricamento JSON dinamico
Carica le traduzioni in modalità lazy durante l'esecuzione
JSON con ambito (namespacing)
Spazi dei nomi di traduzione per pagina
Benchmark delle prestazioni I18n
Cos'è questa metrica?
La dimensione totale compressa con gzip del bundle della libreria di internazionalizzazione. Include solo il provider e la logica di recupero dei contenuti dopo il tree-shaking e la minificazione.
Perché è importante?
Una dimensione della libreria più piccola riduce il payload JavaScript iniziale, portando a tempi di download ed esecuzione più rapidi sul client.
Visualizza come
Dati principali per @lingui/core@6.6.0, misurati il 2026-09-26 (gzip):
Apri la tabella in una finestra modale per visualizzare tutti i dati in modo chiaro
| Configurazione | Dimensione libreria | JS per pagina | Perdita altre lingue | Perdita altre pagine |
|---|---|---|---|---|
| Nessuna i18n (app base) | - | 111.0 KB | 0% | 0% |
| Lingui (configurazione di questa guida) | 56.7 KB | 115.2 KB | 9.3% | 0% |
@intlayer/lingui (compat) | 9.8 KB | 136.7 KB | 9.9% | 0% |
react-intlayer (Intlayer nativo) | 4.5 KB | 126.8 KB | 0% | 0% |
Cosa tenere a mente:
- Carica un solo catalogo per lingua, su richiesta. In questo modo le pagine mantengono una dimensione vicina a quella dell'app di base.
- Il runtime rimane pesante (~57 KB gzip). L'adattatore di compatibilità
@intlayer/lingui(passaggio 16) mantiene le tue macro e riduce il runtime a ~10 KB.
Consulta i dati completi: report di benchmark su TanStack Start e il repository del benchmark.
Confronto delle funzionalità su TanStack Start
Come si posiziona Lingui rispetto alle altre librerie comunemente utilizzate su TanStack Start:
Apri la tabella in una finestra modale per visualizzare tutti i dati in modo chiaro
| Funzionalità | react-intlayer (Intlayer) | use-intl | Paraglide JS | Lingui |
|---|---|---|---|---|
| Traduzioni vicine ai componenti | ✅ Colocate | ❌ JSON centralizzato | ❌ Un file JSON per lingua | ⚠️ Testo sorgente nei componenti |
| Integrazione TypeScript | ✅ Tipi generati automaticamente | ✅ Tramite AppConfig | ✅ Funzioni messaggio tipizzate | ⚠️ Solo macro |
| Rilevamento traduzioni mancanti | ✅ Errori di tipo e avvisi di build | ⚠️ Fallback a runtime | ⚠️ Fallback alla lingua di base | ⚠️ Fallback al testo sorgente |
| Contenuto ricco (JSX, Markdown) | ✅ Supporto diretto | ⚠️ Tag tramite t.rich | ⚠️ Stringhe | ✅ JSX dentro <Trans> |
| Routing localizzato | ✅ Integrato | ❌ {-$locale} manuale | ✅ urlPatterns + riscrittura router | ❌ {-$locale} manuale |
| Cambio lingua senza ricaricamento | ✅ Sì | ✅ Sì | ❌ Ricaricamento completo della pagina | ✅ Sì |
| Pluralizzazione | ✅ Basata su enumerazione | ✅ ICU | ✅ Varianti | ✅ ICU |
| ICU MessageFormat | ✅ Tramite format: "icu" | ✅ Nativo | ⚠️ Tramite plugin inlang | ✅ Nativo |
| Formati di contenuto | ✅ .ts, .json, .md, .yaml... | ⚠️ .json | ⚠️ inlang JSON | ✅ PO, JSON, CSV |
| Traduzione AI | ✅ Provider e chiave personali | ❌ No | ❌ No | ❌ No |
| Editor visuale / CMS | ✅ Editor locale + CMS opzionale | ❌ Piattaforme esterne | ⚠️ App dell'ecosistema inlang | ❌ Piattaforme esterne |
| Helper SEO (hreflang, sitemap) | ✅ Integrati | ❌ Manuale | ⚠️ URL localizzati, resto manuale | ❌ Manuale |
| Dimensione runtime (gzip, benchmark) | 4.5 KB | 75.9 KB | 1.8 KB | 56.7 KB |
| Perdita, migliore configurazione (lingua / pagina) | 0% / 0% | 0% / 0% | 49.7% / 0% | 8.6% / 0% |
| Traduzioni mancanti in CI | ✅ npx intlayer test | ⚠️ Non integrato | ⚠️ Non integrato | ✅ lingui compile --strict |
Le dimensioni del runtime e i dati di perdita provengono dal benchmark di TanStack Start. La perdita è misurata sulla migliore configurazione di ciascuna libreria.
Altre guide su TanStack Start: use-intl, Paraglide JS e Intlayer.
Buone pratiche da seguire
- Imposta
langedirsu<html>a partire dalla lingua della rotta, in modo che siano corretti nell'HTML del server. - Mantieni un URL per lingua con un prefisso, in modo che ogni versione linguistica sia indicizzabile.
- Crea un'istanza
I18nper lingua, non modificare mai un'istanza globale durante l'SSR: due richieste simultanee sovrascriverebbero a vicenda la propria lingua. - Carica solo il catalogo attivo, non importare mai tutti i cataloghi nel codice client.
- Scegli uno stile di macro (
useLingui+tnei componenti,msgper descrittori lazy) e mantienilo con coerenza. Mescolaret,i18n._,i18n.te<Trans>rende il codice più difficile da leggere per le persone e gli assistenti AI. - Esegui
lingui extractnella CI in modo che nessun nuovo messaggio venga rilasciato non tradotto. - Traduci i tuoi metadati e dichiara
canonical,hreflangex-defaultsu ogni pagina. - Genera una sitemap multilingue e robots.txt, e pre-renderizza ogni lingua.
- Usa link reali per il selettore di lingua, in modo che i crawler scoprano ogni lingua.
Consulta la nostra guida su internazionalizzazione e SEO e la guida a hreflang.
Guida passo dopo passo per configurare Lingui in un'applicazione TanStack Start
Ecco la struttura del progetto che creeremo:
Copiare il codice nella clipboard
Installa le dipendenze
bashCopiare il codiceCopiare il codice nella clipboard
- @lingui/core / @lingui/react: runtime,
I18nProvidere le macro (@lingui/core/macro,@lingui/react/macro). - @lingui/cli:
lingui extractper raccogliere i messaggi nei cataloghi. - @lingui/vite-plugin: compila i cataloghi
.poall'importazione, eliminando la necessità dilingui compile. - @lingui/babel-plugin-lingui-macro + @rolldown/plugin-babel: trasformano le macro in fase di compilazione.
- @lingui/core / @lingui/react: runtime,
Centralizza la configurazione delle lingue
La lingua predefinita rimane senza prefisso (
/about), le altre lingue hanno un prefisso (/fr/about).src/i18n/config.tsCopiare il codiceCopiare il codice nella clipboard
Configura Lingui
La configurazione di Lingui riutilizza lo stesso elenco di lingue, in modo che i cataloghi, il router e la sitemap non siano mai in disaccordo.
lingui.config.tsCopiare il codiceCopiare il codice nella clipboard
Aggiungi gli script di estrazione:
package.jsonCopiare il codiceCopiare il codice nella clipboard
i18n:checkfallisce nella CI quando un componente contiene un messaggio che non è stato estratto e committato.Configura Vite
Con
@vitejs/plugin-reactv6, Babel non è più integrato.@rolldown/plugin-babelesegue il plugin macro di Lingui elinguiTransformerBabelPresetelabora solo i file che importano una macro, mantenendo le build veloci.vite.config.tsCopiare il codiceCopiare il codice nella clipboard
Carica i cataloghi per lingua
Il template literal in
import()consente a Vite di emettere un chunk per catalogo e il plugin Lingui vi compila il file.po. Un visitatore francese scarica esclusivamente il catalogo francese.I messaggi compilati sono dati semplici, quindi possono essere restituiti da un loader di rotta, serializzati nell'HTML e riutilizzati durante l'idratazione.
src/i18n/lingui.tsCopiare il codiceCopiare il codice nella clipboard
Affinché TypeScript accetti l'importazione dei file
.po, dichiara il modulo una volta:src/i18n/po.d.tsCopiare il codiceCopiare il codice nella clipboard
Crea il documento radice
La rotta radice legge il parametro opzionale della lingua per impostare
langedirsull'elemento<html>renderizzato dal server.src/routes/__root.tsxCopiare il codiceCopiare il codice nella clipboard
Crea la rotta di layout per le lingue
La cartella
{-$locale}crea un segmento di percorso opzionale:/aboute/fr/aboutcorrispondono entrambi a/{-$locale}/about. Il layout rifiuta i prefissi sconosciuti, carica il catalogo della lingua corrente e fornisce un'istanzaI18ndedicata.src/routes/{-$locale}/route.tsxCopiare il codiceCopiare il codice nella clipboard
Utilizza le traduzioni nelle tue pagine
Scrivi il testo sorgente nel componente. Le macro lo trasformano in ID di messaggio in fase di compilazione e
lingui extractlo individua.<Trans>per contenuti JSX, inclusi elementi nidificati;useLingui().tper stringhe (attributi, props);<Plural>per i plurali ICU.
src/routes/{-$locale}/about.tsxCopiare il codiceCopiare il codice nella clipboard
L'
import()dinamico di un catalogo viene memorizzato nella cache dal sistema di moduli, quindi chiamareloadI18nin diversi loader non scarica il catalogo due volte.Estrai e traduci i tuoi messaggi
Esegui l'estrazione. Lingui scrive ogni messaggio nel catalogo di ciascuna lingua:
bashCopiare il codiceCopiare il codice nella clipboard
Poi traduci il
msgstrdi ciascuna voce:src/locales/fr/messages.poCopiare il codiceCopiare il codice nella clipboard
src/locales/es/messages.poCopiare il codiceCopiare il codice nella clipboard
Per impostazione predefinita, gli ID dei messaggi sono hash del testo sorgente: la modifica del testo inglese crea un nuovo messaggio. Usa ID espliciti (
<Trans id="about.title">About us</Trans>) per i testi che cambiano spesso.Crea un componente di link localizzato
OpzionaleOgni rotta si trova sotto
{-$locale}, quindi i link devono includere il parametro della lingua corrente.src/components/LocalizedLink.tsxCopiare il codiceCopiare il codice nella clipboard
Cambia la lingua dei tuoi contenuti
OpzionaleRenderizza il selettore sotto forma di link, in modo che i crawler trovino ogni versione linguistica.
to="."mantiene la pagina corrente e sostituisce il parametro della lingua. Il loader del layout della lingua recupera quindi il nuovo catalogo.src/components/LocaleSwitcher.tsxCopiare il codiceCopiare il codice nella clipboard
Internazionalizza i tuoi metadati
OpzionaleCiascuna versione linguistica può posizionarsi autonomamente sui motori di ricerca, a condizione che ogni pagina fornisca un
<title>e una descrizione tradotti, un canonico autoreferenziale, unhreflangper lingua piùx-default, impostazioni locali Open Graph e JSON-LD coninLanguage. I metadati vengono tradotti nel loader (passaggio 8) e questo helper costruisce il resto:src/i18n/seo.tsCopiare il codiceCopiare il codice nella clipboard
Internazionalizza la sitemap e robots.txt
OpzionaleLa sitemap elenca ogni URL di ogni lingua e ciascuna voce dichiara tutti i suoi alternativi con
xhtml:link.robots.txtblocca le rotte private in ogni lingua e punta alla sitemap. Rimuovipublic/robots.txtse lo starter ne ha creato uno.src/routes/sitemap[.]xml.tsCopiare il codiceCopiare il codice nella clipboard
src/routes/robots[.]txt.tsCopiare il codiceCopiare il codice nella clipboard
Pre-renderizza ogni lingua
OpzionaleElenca tutti i percorsi localizzati in modo che TanStack Start pre-renderizzi tutte le versioni linguistiche in fase di build:
vite.config.tsCopiare il codiceCopiare il codice nella clipboard
Reindirizza i visitatori alla prima visita e gestisci le pagine 404
OpzionaleUn middleware di richiesta invia un visitatore che atterra su
/alla sua lingua preferita (prima il cookie, poiAccept-Language). I deep link non vengono mai reindirizzati, in modo che i crawler e gli URL condivisi ricevano sempre la pagina richiesta.src/i18n/negotiateLocale.tsCopiare il codiceCopiare il codice nella clipboard
src/start.tsCopiare il codiceCopiare il codice nella clipboard
Per le pagine 404, una rotta catch-all renderizza il componente
notFoundComponentlocalizzato del layout. Contrassegnalo connoindex: React 19 sposta automaticamente il<meta>nell'<head>.src/components/NotFound.tsxCopiare il codiceCopiare il codice nella clipboard
src/routes/{-$locale}/$.tsxCopiare il codiceCopiare il codice nella clipboard
Mantieni le tue macro e riduci il runtime con Intlayer
OpzionaleL'adattatore di compatibilità
@intlayer/linguimantiene il codice sorgente intatto: le macro compilano esattamente come prima e le chiamate risultanti ai18n._(),useLingui()e<Trans>vengono gestite dai dizionari compilati di Intlayer. Nel benchmark, la dimensione del runtime scende da ~56.7 KB a ~9.8 KB gzip.bashCopiare il codiceCopiare il codice nella clipboard
Aggiungi il plugin dopo la trasformazione delle macro, in modo che crei gli alias di
@lingui/coree@lingui/reactverso l'adattatore:vite.config.tsCopiare il codiceCopiare il codice nella clipboard
I cataloghi vengono sincronizzati con il plugin sync JSON (cataloghi JSON) o il plugin sync PO (cataloghi PO). Consulta la configurazione completa nella guida alla compatibilità con Lingui e un confronto dettagliato in Lingui vs @intlayer/lingui.
Automatizza le tue traduzioni con Intlayer
OpzionaleLingui estrae i messaggi, ma compilare a mano dozzine di cataloghi richiede la maggior parte del tempo. Intlayer è gratuito e open source, e i suoi strumenti funzionano perfettamente a fianco di Lingui:
- Traduci con l'AI usando la tua chiave API e il tuo provider. Consulta auto fill e la CLI.
- Mantieni i tuoi file PO come unica fonte di verità con il plugin sync PO.
- Verifica le traduzioni mancanti nella CI. Consulta testare le tue traduzioni.
- Esegui un audit del sito distribuito per individuare
hreflangmancanti, canonical errati e perdite di lingue con il comando scan.
Domande frequenti
Sì. Lingui non dispone di un'integrazione dedicata per TanStack Start, ma il suo plugin Vite e il plugin macro Babel funzionano così come sono. I due aspetti chiave da configurare correttamente sono l'esecuzione delle macro tramite @rolldown/plugin-babel (Vite 8 e @vitejs/plugin-react v6 non includono più Babel) e la creazione di un'istanza I18n per ciascuna lingua anziché attivarne una globale durante l'SSR.
Sul server, un singolo processo renderizza molte richieste contemporaneamente. Chiamare i18n.activate("fr") su un oggetto condiviso cambierebbe la lingua di un'altra richiesta renderizzata in inglese in parallelo. setupI18n crea un'istanza isolata per ogni lingua, garantendo la sicurezza concorrente.
No. @lingui/vite-plugin compila i cataloghi .po al momento dell'importazione. Devi solo eseguire lingui extract per raccogliere i nuovi messaggi.
Dichiarali con la macro msg e traducili nel loader della rotta con i18n._(msg`...`). Il loader restituisce stringhe semplici, quindi head() rimane sincrono e i valori vengono serializzati per l'idratazione. Il passaggio 8 e il passaggio 12 mostrano la configurazione completa.
Il benchmark misura circa 56.7 KB gzip per il runtime. Con un catalogo per lingua caricato su richiesta, le pagine pesano circa 115 KB rispetto a 111 KB senza i18n. L'importazione statica di tutti i cataloghi aumenta il peso a circa 152 KB.
Sì. L'adattatore @intlayer/lingui mantiene le macro e sostituisce il runtime. Puoi quindi migrare i componenti a useIntlayer uno alla volta. Consulta gli adattatori di compatibilità.
Commenti
Ancora nessun commento. Sii il primo a condividere i tuoi pensieri.
