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 Paraglide JS nel 2026
Indice dei contenuti
Cos'è Paraglide JS?
Paraglide JS (di inlang) è una libreria i18n basata su compilatore. Invece di distribuire un runtime che cerca le chiavi in un oggetto JSON, compila ogni messaggio in una funzione JavaScript tipizzata (m.about_title()). I messaggi non utilizzati possono essere rimossi dal bundler (tree-shaking), e un refuso in una chiave diventa un errore di compilazione.
Paraglide è l'approccio i18n utilizzato negli esempi ufficiali di TanStack Router, e si integra con TanStack Start attraverso tre elementi:
- un plugin Vite che compila i messaggi e il runtime in
src/paraglide; - un middleware server che risolve la lingua di ogni richiesta;
- una riscrittura del router che mappa gli URL localizzati (
/fr/about) al tuo albero delle route (/about), eliminando la necessità di un segmento$locale.
Questa guida configura tutti e tre questi aspetti, per poi trattare tutto ciò che Paraglide lascia a te: lang e dir, selettore di lingua, metadati tradotti, canonical, hreflang con x-default, Open Graph, JSON-LD, sitemap, robots.txt, pre-rendering e pagine 404 localizzate.
Cerchi un altro stack? Consulta la guida TanStack Start + use-intl, la guida TanStack Start + Lingui o la guida TanStack Start + Intlayer.
Vuoi confrontare i due approcci basati su compilatore? Leggi Intlayer è più leggero di Paraglide?.
Cosa dice il benchmark su Paraglide con TanStack Start
Il benchmark i18n esegue la stessa app TanStack Start di 10 pagine e 10 lingue con ciascuna delle 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 @inlang/paraglide-js@2.15.1, misurati il 26-09-2026 (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 | Caricamento pagina |
|---|---|---|---|---|---|
| Nessuna i18n (app base) | - | 111.0 KB | 0% | 0% | 15.7 ms |
| Paraglide JS | 1.8 KB | 125.1 KB | 49.7% | 0% | 22.1 ms |
react-intlayer | 4.5 KB | 126.8 KB | 0% | 0% | 14.8 ms |
use-intl | 75.9 KB | 128.7 KB | 0% | 0% | 17.4 ms |
| Lingui | 56.7 KB | 120.2 KB | 8.6% | 0% | 21.9 ms |
Punti chiave da considerare:
- Il runtime è minuscolo e le pagine non hanno perdite. Il runtime viene generato in base alla tua configurazione e i messaggi vengono importati solo dove vengono utilizzati.
- Le lingue non utilizzate trapelano (leak). Ciascuna funzione di messaggio contiene tutte le lingue, quindi circa la metà delle stringhe tradotte inviate a una pagina appartiene a lingue che il visitatore non usa. Più lingue aggiungi, maggiore diventa questa quota.
- Il caricamento della pagina è il più lento del gruppo, in parte perché la lingua viene risolta tramite strategie a ogni chiamata anziché essere letta da un contesto React.
Consulta i dati completi: Report del benchmark TanStack Start e il repository del benchmark.
Confronto delle funzionalità su TanStack Start
Come si confronta Paraglide JS con le 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 vicino ai componenti | ✅ Co-locate | ❌ 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 | ❌ Manuale {-$locale} | ✅ urlPatterns + rewrite router | ❌ Manuale {-$locale} |
| Cambio lingua senza ricaricamento | ✅ Sì | ✅ Sì | ❌ Ricaricamento completo 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 | ⚠️ JSON inlang | ✅ PO, JSON, CSV |
| Traduzione con IA | ✅ Provider e chiave propri | ❌ No | ❌ No | ❌ No |
| Editor visuale / CMS | ✅ Editor locale + CMS opzionale | ❌ Piattaforme esterne | ⚠️ App ecosistema inlang | ❌ Piattaforme esterne |
| Helper SEO (hreflang, sitemap) | ✅ Integrati | ❌ Manuale | ⚠️ URL localizzati, resto manuale | ❌ Manuale |
| Dimensione runtime (gzip, bench) | 4.5 KB | 75.9 KB | 1.8 KB | 56.7 KB |
| Leak, miglior setup (lingua/pag) | 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 leak provengono dal benchmark TanStack Start. Il leak è misurato sulla migliore configurazione di ciascuna libreria.
Altre guide su TanStack Start: Lingui, use-intl e Intlayer.
Buone pratiche da seguire
- Imposta
langedirsu<html>dalla lingua risolta, sul server. - Mantieni un URL per lingua con una strategia a prefisso (
/fr/about), in modo che ogni versione linguistica sia indicizzabile. - Metti
urlal primo posto nella strategia della lingua, così l'URL è l'unica fonte di verità e i crawler ottengono la pagina richiesta. - Usa chiavi di messaggio piatte e descrittive (
about_title) che si mappano chiaramente ai nomi delle funzioni. - Effettua il commit dei tuoi file
messages/*.json, non della cartella generatasrc/paraglide, per evitare conflitti di merge sui file generati. - Traduci i metadati e dichiara
canonical,hreflangex-defaultsu ogni pagina. - Genera una sitemap multilingue e robots.txt, ed esegui il pre-rendering di ogni lingua.
- Usa veri link per il selettore di lingua, così i crawler scoprono tutte le lingue.
Consulta la nostra guida su internazionalizzazione e SEO e la guida hreflang.
Guida passo-passo per configurare Paraglide JS in un'applicazione TanStack Start
Ecco la struttura del progetto che creeremo:
Copiare il codice nella clipboard
Nota che non c'è alcuna cartella $locale: la riscrittura del router rimuove il prefisso prima della corrispondenza delle route.
Installa le dipendenze
Inizia da un progetto TanStack Start, quindi inizializza Paraglide. Il comando init crea
project.inlang/settings.json, un primo filemessages/en.jsone installa il pacchetto.bashCopiare il codiceCopiare il codice nella clipboard
- @inlang/paraglide-js: il compilatore e il relativo plugin Vite. Non c'è alcun pacchetto runtime da installare: il runtime viene generato direttamente nel tuo progetto.
Configura le tue lingue
project.inlang/settings.jsonè l'unica fonte di verità per le lingue. Il plugin del formato dei messaggi legge un file JSON per ciascuna lingua.project.inlang/settings.jsonCopiare il codiceCopiare il codice nella clipboard
Configura il plugin Vite e la strategia URL
Il plugin compila i messaggi a ogni modifica. Tre opzioni sono importanti per TanStack Start:
strategy: l'elenco ordinato dei punti da cui leggere la lingua.urlper primo rende l'URL l'unica fonte di verità.cookieepreferredLanguagevengono utilizzati dal middleware quando l'URL non specifica una lingua.urlPatterns: come una lingua viene mappata a un URL. Le lingue non predefinite sono elencate per prime, poiché il primo pattern corrispondente ha la precedenza. Qui la lingua predefinita rimane senza prefisso (/about), mentre le altre lingue ricevono il prefisso (/fr/about).outputStructure: "message-modules": un modulo per messaggio, che consente al bundler di escludere i messaggi non importati da una pagina.
vite.config.tsCopiare il codiceCopiare il codice nella clipboard
Aggiungi la cartella generata a
.gitignore. Viene ricreata sia durantedevche durantebuild:.gitignoreCopiare il codiceCopiare il codice nella clipboard
Crea i file di traduzione
Ogni chiave diventa una funzione esportata da
src/paraglide/messages. Chiavi piatte in snake_case producono i nomi di funzione più puliti. Le variabili usano segnaposto{name}.messages/en.jsonCopiare il codiceCopiare il codice nella clipboard
messages/fr.jsonCopiare il codiceCopiare il codice nella clipboard
I plurali utilizzano la sintassi delle varianti del formato messaggi inlang:
messages/en.jsonCopiare il codiceCopiare il codice nella clipboard
Aggiungi il middleware server
Il middleware risolve la lingua di ogni richiesta tramite la tua strategia e la rende disponibile a
getLocale()per l'intero rendering sul server, attraverso uno scopeAsyncLocalStorage. Questo rende sicure le richieste simultanee in lingue diverse.In TanStack Start, racchiudi l'entry server predefinito:
src/server.tsCopiare il codiceCopiare il codice nella clipboard
Riscrivi gli URL localizzati nel router
L'opzione
rewritedi TanStack Router traduce gli URL ai confini del router:- input:
/fr/aboutviene de-localizzato in/aboutprima del matching delle route, consentendo a una singola routeabout.tsxdi servire ogni lingua; - output: ogni
hrefgenerato (link, reindirizzamenti, navigazione) viene localizzato per la lingua attiva, così<Link to="/about">renderizza/fr/aboutsu una pagina francese.
src/router.tsxCopiare il codiceCopiare il codice nella clipboard
Poiché i link vengono localizzati dalla riscrittura, non serve un componente personalizzato
LocalizedLink: usa il componenteLinkstandard di TanStack Router.- input:
Crea il documento root
getLocale()restituisce la lingua risolta dal middleware sul server e la lingua dall'URL nel browser, garantendo chelangedirsiano identici sia nell'HTML del server che dopo l'idratazione.src/i18n/config.tsCopiare il codiceCopiare il codice nella clipboard
src/routes/__root.tsxCopiare il codiceCopiare il codice nella clipboard
Utilizza le traduzioni nelle tue pagine
I messaggi sono semplici funzioni: importa
m, chiama la funzione e passa le variabili come oggetto. Tutto è tipizzato, incluse le variabili.src/routes/index.tsxCopiare il codiceCopiare il codice nella clipboard
src/routes/about.tsxCopiare il codiceCopiare il codice nella clipboard
Una funzione di messaggio accetta anche una lingua esplicita:
m.about_title({}, { locale: "fr" }). Questo è utile nel codice server che genera una lingua diversa da quella della richiesta, come per le email.Cambia la lingua dei tuoi contenuti
OpzionaleRenderizza il selettore come link con
localizeHref, in modo che i crawler scoprano tutte le lingue.setLocalememorizza la scelta nel cookie e ricarica la pagina nella nuova lingua: un ricaricamento completo è il comportamento previsto in Paraglide, poiché le funzioni di messaggio leggono la lingua a ogni chiamata anziché sottoscriversi a uno stato React.src/components/LocaleSwitcher.tsxCopiare il codiceCopiare il codice nella clipboard
Internazionalizza i tuoi metadati
OpzionaleOgni versione linguistica può posizionarsi autonomamente sui motori di ricerca, a patto che ogni pagina esponga:
- un
<title>e unadescriptiontradotti; - un URL canonical che punta a se stesso;
- un alternativo
hreflangper ogni lingua, piùx-default; - tag Open Graph
og:locale,og:locale:alternateeog:url; - JSON-LD con
inLanguage.
localizeUrldi Paraglide crea gli URL alternativi a partire dai tuoiurlPatterns, evitando qualsiasi discrepanza con il routing reale:src/i18n/seo.tsCopiare il codiceCopiare il codice nella clipboard
- un
Internazionalizza la tua sitemap
OpzionaleUna sitemap multilingue elenca ogni URL per ogni lingua, e ogni voce dichiara tutti i suoi alternativi tramite
xhtml:link:src/routes/sitemap[.]xml.tsCopiare il codiceCopiare il codice nella clipboard
Internazionalizza il tuo robots.txt
OpzionaleLe route private esistono in tutte le lingue, pertanto le regole
Disallowdevono coprire ogni percorso localizzato. Rimuovipublic/robots.txtse il template iniziale ne ha creato uno, quindi servilo da una route:src/routes/robots[.]txt.tsCopiare il codiceCopiare il codice nella clipboard
Esegui il pre-rendering di ogni lingua
OpzionaleElenca il percorso localizzato di ciascuna pagina in modo che TanStack Start effettui il pre-rendering di tutte le versioni linguistiche.
localizeHrefè codice generato privo di dipendenze dal browser, quindi può essere eseguito invite.config.ts, ma il file esiste solo dopo una prima compilazione. Elencare i percorsi manualmente, come illustrato sotto, evita questo problema di ordine di esecuzione:vite.config.tsCopiare il codiceCopiare il codice nella clipboard
Poiché il selettore renderizza link reali,
crawlLinks: trueindividua anche le pagine che potresti aver dimenticato di elencare.Gestisci pagine 404 localizzate
OpzionaleCon la riscrittura,
/fr/does-not-existviene mappato come/does-not-exist, egetLocale()restituisce comunquefr, quindi ilnotFoundComponentroot del passaggio 7 renderizza in francese. Una route catch-all garantisce che anche i percorsi profondi raggiungano questa logica. Contrassegna la pagina connoindex: React 19 sposta automaticamente il<meta>nell'<head>.src/components/NotFound.tsxCopiare il codiceCopiare il codice nella clipboard
src/routes/$.tsxCopiare il codiceCopiare il codice nella clipboard
Accedi alla lingua nelle Server Function
OpzionaleLe server function vengono eseguite all'interno dello scope del middleware di Paraglide, quindi
getLocale()funziona anche al loro interno:src/server/sendWelcomeEmail.tsCopiare il codiceCopiare il codice nella clipboard
Confronto con Intlayer
OpzionaleNon esiste un adapter diretto da Paraglide a Intlayer, poiché entrambi seguono lo stesso principio: compilare i contenuti in fase di build e distribuire il minor runtime possibile. Le differenze risiedono in ciò che raggiunge il browser e nel modo in cui i contenuti sono organizzati:
- Lingue: Intlayer carica dizionari dinamici per lingua (0% di leak di lingua nel benchmark), mentre ciascuna funzione di messaggio di Paraglide include tutte le lingue (49.7%).
- Organizzazione dei contenuti: i contenuti possono trovarsi in file
.content.tsaccanto a ciascun componente, oppure in file centralizzati. Vedi i18n per componente vs centralizzato. - Cambio lingua: i contenuti vengono letti da un contesto React, quindi il cambio di lingua riesegue il render senza dover ricaricare la pagina.
- Codice generato: non viene generato nulla all'interno di
src, quindi non c'è nulla da rigenerare prima di un commit.
Se provieni da un'altra libreria invece che da Paraglide, gli adapter di compatibilità mantengono le API di
use-intl,next-intl,react-i18next,react-intlo Lingui sostituendo semplicemente il runtime sottostante.Vedi Intlayer è più leggero di Paraglide? e la guida Intlayer per TanStack Start.
Automatizza le tue traduzioni con Intlayer
OpzionaleParaglide renderizza le traduzioni, ma non ti aiuta a produrle. Intlayer è gratuito e open source, e i suoi strumenti risultano utili anche in un progetto basato su Paraglide:
- Traduci con l'IA usando la tua chiave API e il provider che preferisci. Vedi auto-riempimento e la CLI.
- Mantieni i tuoi file JSON come unica fonte di verità con il plugin sync JSON.
- Verifica le traduzioni mancanti in CI. Vedi testare le tue traduzioni.
- Analizza il tuo sito distribuito per individuare tag
hreflangmancanti, canonical errati e leak di lingua con il comando scan.
Domande Frequenti
È un'opzione solida: è utilizzata negli esempi ufficiali di TanStack Router, ha il runtime più compatto del benchmark (~1.8 KB gzip) e i messaggi sono completamente tipizzati. I compromessi principali sono che ogni funzione di messaggio include tutte le lingue (inviando circa la metà delle stringhe tradotte a visitatori di altre lingue) e che il cambio di lingua comporta il ricaricamento della pagina.
No. La riscrittura (rewrite) del router rimuove il prefisso della lingua prima del matching della route e lo riapplica ai link generati, consentendo a un unico file about.tsx di servire /about, /fr/about ed /es/about.
Le funzioni di messaggio leggono la lingua al momento della chiamata e non sono sottoscritte a uno stato React. setLocale ricarica quindi la pagina per impostazione predefinita, in modo che ogni messaggio venga renderizzato nuovamente nella nuova lingua. È possibile passare { reload: false }, ma in tal caso dovrai gestire manualmente il re-render dell'albero dei componenti.
È preferibile non farlo. La cartella viene rigenerata a ogni dev e build, e committarla può provocare conflitti di merge su file generati automaticamente. Effettua invece il commit di messages/*.json e project.inlang/settings.json.
Usa localizeUrl per creare un URL assoluto per ciascuna lingua nella funzione head() della route, e aggiungi un tag x-default che punta alla lingua di base. Il passaggio 10 fornisce un helper riutilizzabile, e il passaggio 11 aggiunge gli stessi collegamenti alternativi alla sitemap.
I messaggi non utilizzati vengono rimossi quando si usa outputStructure: "message-modules", evitando perdite di contenuti tra pagine diverse. Le lingue non utilizzate, invece, non vengono rimosse: ogni funzione di messaggio include tutte le traduzioni, motivo per cui il benchmark registra una dispersione (leak) di lingua del 49.7%.
Commenti
Ancora nessun commento. Sii il primo a condividere i tuoi pensieri.
