Questa pagina ha un modello di applicazione disponibile.
Pose una domanda e ottieni un riassunto del documento facendo riferimento a questa pagina e al provider AI di tua scelta
Cronologia delle versioni
- "Utilizzo del middleware e degli hook di remix-intlayer"v9.5.519/09/2026
- "Documentazione iniziale per Remix 3"v9.5.009/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
Traduci il tuo sito web Remix 3 usando Intlayer
Questa guida illustra come integrare Intlayer per un'internazionalizzazione fluida nelle applicazioni Remix 3 con routing basato sulla lingua, dichiarazioni di contenuti con sicurezza dei tipi, componenti JSX renderizzati lato server e supporto multi-runtime su Node.js, Bun, Deno e Cloudflare Workers.
Cos'è Remix 3?
Remix 3 rappresenta una fondamentale evoluzione architetturale verso un framework web componibile e indipendente dal runtime, costruito interamente su standard web. Anziché essere vincolato a bundler specifici o API proprietarie del server, Remix 3 è distribuito come pacchetti componibili a scopo singolo:
remix/fetch-router(oremix/router): Routing leggero e conforme agli standard basato sulle Fetch API (RequesteResponse).remix/ui: Un modello di componenti JSX (jsxImportSource: "remix/ui"). Un componente è una funzione di setup che restituisce una funzione di render, simile a React ma con lo stato gestito in semplici closure JavaScript.remix/middleware/render: Installacontext.render(<Page />)su ogni richiesta, trasmettendo l'albero JSX in unaResponseHTML.remix/node-fetch-server: Adattatori server per Node.js, con supporto nativo per Bun, Deno e runtime edge.remix/cookie: Parsing e serializzazione di cookie crittograficamente sicuri.
Combinato con Intlayer e il pacchetto remix-intlayer, un middleware di locale più gli stessi hook useIntlayer / useDictionary / useLocale di react-intlayer, associati al contesto di richiesta di Remix, ottieni un sistema completo di internazionalizzazione che offre sicurezza in fase di compilazione, traduzioni automatizzate con IA, rendering lato server a zero overhead e routing fluido delle locali.
Sommario
Perché scegliere Intlayer rispetto alle alternative?
Rispetto alle soluzioni tradizionali come i18next o caricatori di traduzioni personalizzati, Intlayer offre un'esperienza di sviluppo integrata e ottimizzata per l'architettura web moderna:
Intlayer è progettato per funzionare in modo nativo con gli standard web (Request, Response, Headers e URL). remix-intlayer si integra nel router Fetch di Remix 3 come un middleware leggero, estraendo la locale dai percorsi URL, dai cookie o dalle intestazioni Accept-Language ed esponendola al resto della richiesta, handler, viste e componenti remix/ui, senza doverla passare manualmente né vincolarti a un runtime specifico.
Dì addio alle chiavi JSON non tipizzate e agli errori di runtime dovuti a chiavi mancanti. Intlayer applica i controlli di TypeScript su tutte le lingue dichiarate, avvisandoti in fase di compilazione se una traduzione manca o non è valida.
Remix 3 esegue il rendering dei componenti JSX sul server e trasmette l'HTML al client. Solo il testo risolto per la lingua richiesta viene inviato nel flusso di output. Non sono necessari bundle di idratazione client né pesanti cataloghi di traduzione, a meno che un componente non sia esplicitamente contrassegnato come clientEntry.
Intlayer posiziona le dichiarazioni di contenuto (.content.ts) accanto alla logica delle route, riducendo il contesto di token necessario per i Large Language Models (LLM). I comandi CLI integrati come intlayer fill e intlayer test ti consentono di automatizzare le traduzioni nelle pipeline di CI/CD al costo diretto del tuo fornitore di IA.
Oltre ai flussi di lavoro incentrati sul codice, Intlayer fornisce un Editor Visivo self-hosted e un CMS Remoto, consentendo a redattori e traduttori di aggiornare i contenuti senza dover ridistribuire l'applicazione.
Guida passo dopo passo
Consulta il Modello di Applicazione su GitHub.
Installare le dipendenze
Installa
intlayer,remix-intlayereremix(versione 3) utilizzando il tuo gestore di pacchetti preferito:bashCopiare il codiceCopiare il codice nella clipboard
intlayer: Motore principale di internazionalizzazione per la gestione della configurazione, la dichiarazione dei dizionari (t(),Dictionary), gli strumenti CLI e l'interprete a runtime.remix-intlayer: L'integrazione con Remix 3: il middleware routerintlayer()che risolve la locale di ogni richiesta, e gli hookuseIntlayer,useDictionaryeuseLocaleche la leggono in qualunque punto successivo.remix: Il pacchetto unificato del framework Remix 3 che esportaremix/router,remix/routes,remix/ui,remix/middleware/rendereremix/node-fetch-server.
Configurare Intlayer
Architettura
In questa architettura, il middleware
intlayer()diremix-intlayerè registrato increateRouter()prima del middlewarerender(). Rimuove il prefisso della locale prima della corrispondenza del router, in modo che le route siano dichiarate una sola volta insrc/routes.tssenza un segmento:locale, ed esegue il resto della richiesta all'interno di uno scopeAsyncLocalStorage, consentendo auseIntlayer/useLocaledi leggere la locale senza argomenti nei gestori di route e nelle visteremix/ui. Le dichiarazioni di contenuto sono posizionate accanto alle tue viste insrc/:bashCopiare il codiceCopiare il codice nella clipboard
Configurazione
Crea un file
intlayer.config.tsnella radice del progetto per dichiarare le lingue supportate e le impostazioni di internazionalizzazione:intlayer.config.tsCopiare il codiceCopiare il codice nella clipboard
import { Locales, type IntlayerConfig } from "intlayer"; const config: IntlayerConfig = { internationalization: { locales: [ Locales.ENGLISH, Locales.FRENCH, Locales.SPANISH, Locales.ITALIAN, ], defaultLocale: Locales.ENGLISH, }, }; export default config;Per ulteriori opzioni di configurazione, consulta la documentazione di configurazione.
Dichiarare i contenuti multilingue
Dichiara i tuoi contenuti localizzati in un file
.content.ts:src/home.content.tsCopiare il codiceCopiare il codice nella clipboard
import { t, type Dictionary } from "intlayer"; const homeContent = { key: "home", content: { title: t({ it: "Benvenuto su Remix 3", en: "Welcome to Remix 3", fr: "Bienvenue sur Remix 3", es: "Bienvenido a Remix 3", }), description: t({ it: "Un'applicazione componibile basata su standard web con i18n nativa.", en: "A composable, web-standard application with native i18n.", fr: "Une application composable basée sur les standards web avec i18n native.", es: "Una aplicación componible basada en estándares web con i18n nativa.", }), switchLanguage: t({ it: "Cambia lingua:", en: "Switch language:", fr: "Changer de langue :", es: "Cambiar idioma:", }), }, } satisfies Dictionary; export default homeContent;Intlayer supporta anche i formati JSON, YAML e CommonJS. Vedi la Documentazione sulla Dichiarazione dei Contenuti.
Compilare i dizionari Intlayer
Compila le definizioni dei dizionari per generare i tipi TypeScript e i registri di runtime:
bashCopiare il codiceCopiare il codice nella clipboard
Ciò compila i tuoi contenuti nella directory degli artefatti
.intlayer, offrendo completamento automatico completo in TypeScript e un rapido recupero dei dizionari.Aggiungere il middleware Intlayer
Remix 3 fornisce una pipeline di middleware componibile tramite
createRouter({ middleware: [...] }).remix-intlayerfornisce il middlewareintlayer(). Per ogni richiesta in entrata risolve la locale utilizzando:- L'URL, in ogni modalità di routing tranne
no-prefix: il prefisso del percorso (es./ito/fr) o il parametro di ricerca?locale=. - La locale memorizzata dal client: il cookie di archiviazione (
INTLAYER_LOCALE) o l'intestazione personalizzata (x-intlayer-locale). - La negoziazione standard di
Accept-Language, ricorrendo alla tuadefaultLocaleconfigurata.
Il risultato viene memorizzato nel contesto di richiesta di Remix come
context.intlayer(ocontext.get(Intlayer)), conlocale,defaultLocaleeavailableLocales. Il middleware esegue quindi il resto della richiesta all'interno di un ambitoAsyncLocalStorageassociato a tale contesto, consentendo agli hook del pacchetto di leggere la locale senza argomenti, sia nei gestori di route che nelle viste e nei componentiremix/ui:typescriptCopiare il codiceCopiare il codice nella clipboard
useIntlayer("home", "fr")ouseIntlayer("faq", { item: 2 })sovrascrivono la locale della richiesta per una singola chiamata, euseDictionary(homeContent)legge un dizionario importato anziché una chiave. Al di fuori di una richiesta, gli hook ricorrono alla locale predefinita.Il middleware prepara anche i dizionari Intlayer all'avvio del server, in modo che un
intlayer buildmancante non lasci il registro vuoto.Imposta
routing.enableProxy: falseinintlayer.config.tsper mantenere solo la risoluzione della locale e gestire il routing autonomamente.intlayer({ ignore })lascia invariate le richieste corrispondenti (un prefisso API, ad esempio), eintlayer({ isDevServer })controlla se la locale memorizzata guida i reindirizzamenti nella modalità automatica predefinita dienableProxy.- L'URL, in ogni modalità di routing tranne
Definire route con sicurezza dei tipi
Definisci le route della tua applicazione utilizzando
route()daremix/routes:src/routes.tsCopiare il codiceCopiare il codice nella clipboard
import { route } from "remix/routes"; export const routes = route({ // Route della lingua predefinita home: "/", // Route localizzata con segmento dinamico :locale localizedHome: "/:locale", });L'utilizzo di
route()fornisce una generazione di URL type-safe in tutta l'applicazione:typescriptCopiare il codiceCopiare il codice nella clipboard
Renderizzare pagine localizzate con JSX
Remix 3 esegue il rendering dell'interfaccia utente con componenti JSX provenienti da
remix/ui. Un componente è una funzione di setup che riceve unHandlee restituisce una funzione di render. Il setup viene eseguito una sola volta per istanza, il render viene eseguito a ogni aggiornamento e le props vengono lette tramitehandle.props.Inizia con un guscio condiviso
Documentche imposta gli attributi<html lang="..." dir="...">dalla locale risolta dal middleware:src/views/document.tsxCopiare il codiceCopiare il codice nella clipboard
import { getHTMLTextDir } from "intlayer"; import { useLocale } from "remix-intlayer"; import type { Handle, RemixNode } from "remix/ui"; type DocumentProps = { title: string; children?: RemixNode; }; export const Document = (handle: Handle<DocumentProps>) => () => { const { title, children } = handle.props; const { locale } = useLocale(); return ( <html lang={locale} dir={getHTMLTextDir(locale)}> <head> <meta charSet="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <title>{title}</title> </head> <body>{children}</body> </html> ); };Poi crea la pagina home. Legge il dizionario localizzato con
useIntlayere mostra un selettore di lingua:src/views/home.tsxCopiare il codiceCopiare il codice nella clipboard
import { getLocaleName, getLocalizedUrl, getPathWithoutLocale } from "intlayer"; import { useIntlayer, useLocale } from "remix-intlayer"; import { Document } from "./document"; export const HomePage = () => () => { const { locale, availableLocales } = useLocale(); const home = useIntlayer("home"); const pathWithoutLocale = getPathWithoutLocale(); return ( <Document title={home.title}> <header> <nav aria-label="Languages"> <span>{home.switchLanguage}</span> <ul> {availableLocales.map((localeItem) => { const isActive = localeItem === locale; return ( <li key={localeItem} class="p-1"> <a href={getLocalizedUrl(pathWithoutLocale, localeItem)} class={isActive ? "active" : undefined} aria-current={isActive ? "page" : undefined} > {getLocaleName(localeItem, locale)} </a> </li> ); })} </ul> </nav> </header> <main> <h1>{home.title}</h1> <p>{home.description}</p> </main> </Document> ); };JSX in Remix non è React:
classsi scrive così com'è (classNameè comunque accettato) e i nuovi rendering vengono attivati esplicitamente conhandle.update(). I valori interpolati vengono sottoposti a escape automaticamente. Gli hook Intlayer sono semplici funzioni che leggono l'ambito della richiesta, quindi possono essere chiamati sia dalla funzione di setup che da quella di rendering.Collegare il router e il server
Aggiungi il middleware
render()diremix/middleware/renderaccanto al middleware di Intlayer. Installacontext.render(node, init)su ogni richiesta, trasmettendo l'albero JSX in unaResponseHTML (anteponendo<!DOCTYPE html>e impostando l'headerContent-Type):src/router.tsxCopiare il codiceCopiare il codice nella clipboard
import { isDeclaredLocale } from "intlayer"; import { intlayer } from "remix-intlayer"; import { render } from "remix/middleware/render"; import { createRouter } from "remix/router"; import { routes } from "./routes"; import { HomePage } from "./views/home"; // 1. Initialize router with Intlayer + render middleware export const router = createRouter({ middleware: [intlayer(), render()], }); // 2. Map route handlers router.map(routes, { actions: { // Default locale route home(context) { return context.render(<HomePage />); }, // Localized route localizedHome(context) { if (!isDeclaredLocale(context.params.locale)) { return new Response("Not Found", { status: 404 }); } return context.render(<HomePage />); }, }, });context.renderaccetta unResponseInitopzionale come secondo argomento, ad es.context.render(<NotFoundPage />, { status: 404 }). La locale risolta rimane accessibile dall'handler comecontext.intlayer.locale, ad esempio per costruire una rispostaResponse.json.Infine, esponi il router tramite un gestore
fetchstandard. Lo stesso router funziona su Node.js, Bun, Deno e Cloudflare Workers:src/server.tsCopiare il codiceCopiare il codice nella clipboard
import * as http from "node:http"; import { createRequestListener } from "remix/node-fetch-server"; import { router } from "./router"; const PORT = Number(process.env.PORT || 3000); // Node.js const server = http.createServer( createRequestListener((request) => router.fetch(request)) ); server.listen(PORT, () => { console.log(`Server in esecuzione su http://localhost:${PORT}`); }); // Bun / Deno / Cloudflare Workers export default { port: PORT, fetch(request: Request) { return router.fetch(request); }, };Verificare e completare automaticamente le traduzioni
Intlayer include una CLI per rilevare le traduzioni mancanti e completarle automaticamente tramite intelligenza artificiale:
bashCopiare il codiceCopiare il codice nella clipboard
Configurazione TypeScript
Punta JSX al runtime remix/ui e assicurati che il tuo tsconfig.json includa i tipi generati in .intlayer:
Copiare il codice nella clipboard
jsxImportSource: "remix/ui"è ciò che permette a<HomePage />di risolversi con ilcreateElementdi Remix anziché con quello di React.
Conclusione
Con Remix 3 e Intlayer, disponi di uno stack leggero, completamente tipizzato e multipiattaforma, fedele agli standard web aperti. La tua applicazione può scalare con facilità da semplici pagine marketing localizzate a servizi edge distribuiti globalmente.
