Integrazione con Astro (ts-intl-astro)
ts-intl-astro è un pacchetto di integrazione per Astro sviluppato sulla libreria principale @aaakul/ts-intl. Gestendo lo stato della lingua della richiesta tramite contesto asincrono (AsyncLocalStorage), elimina la necessità di passare le prop di lingua lungo l’albero dei componenti (Prop Drilling).
Caratteristiche principali
- Zero Prop Drilling: Grazie ad
AsyncLocalStoragee al middleware di Astro in Node.js e nei moderni runtime, qualsiasi componente può chiamare direttamenteuseTranslations()per accedere alle funzioni di traduzione relative alla lingua attiva della richiesta. - Iniezione automatica del middleware: Registrando l’integrazione in
astro.config.mjs, viene inserito automaticamente un pre-middleware nella pipeline di rendering di Astro per determinare la lingua della pagina attiva. Supportacontext.currentLocale, i parametri di routing ([lang],[locale]) e l’analisi del percorso URL. - Rigorosa type safety: Eredita l’inferenza completa dei tipi in fase di compilazione da
ts-intl, compresi vincoli sui namespace, autocompletamento delle chiavi, convalida dei parametri ICU e controllo di parità dei dizionari multilingua.
Installazione
Installa ts-intl-astro e le sue dipendenze nel tuo progetto Astro:
pnpm add ts-intl-astro
# oppure
npm install ts-intl-astro
# oppure
yarn add ts-intl-astro
Configurazione rapida
1. Inizializzare l’istanza i18n
Crea ed esporta gli hook di traduzione e la configurazione dell’istanza in src/i18n/index.ts:
// src/i18n/index.ts
import { createAstroI18n } from "ts-intl-astro";
import itIT from "./messages/it-IT";
import enUS from "./messages/en-US";
export const {
useTranslations,
useLocale,
useFormatter,
languages,
defaultLanguage,
} = createAstroI18n({
defaultLanguage: "it-IT",
messages: {
"it-IT": itIT,
"en-US": enUS,
},
});
export type SupportedLanguage = (typeof languages)[number];
2. Registrare l’integrazione Astro
Importa e abilita tsIntl nel file astro.config.mjs:
// astro.config.mjs
import { defineConfig } from "astro/config";
import tsIntl from "ts-intl-astro";
export default defineConfig({
integrations: [tsIntl()],
});
L’integrazione registra automaticamente il middleware di contesto durante la build e l’esecuzione di Astro. Quando una pagina gestisce una richiesta o genera pagine statiche, il middleware determina il locale della route e inietta il contesto attivo nello scope della richiesta.
Utilizzo nei componenti
Con il middleware di contesto abilitato, i componenti non devono dichiarare né accettare una prop lang:
Utilizzo di base
---
// src/components/Header.astro
import { useTranslations, useLocale } from "@/i18n";
const t = useTranslations("nav");
const lang = useLocale();
---
<header class="flex items-center justify-between p-4">
<nav class="space-x-4">
<a href={`/${lang}`}>{t("home")}</a>
<a href={`/${lang}/docs`}>{t("docs")}</a>
<a href={`/${lang}/pricing`}>{t("pricing")}</a>
</nav>
</header>
Override esplicito della lingua (Locale Override)
Quando un componente isolato deve essere renderizzato in una lingua specifica (ad esempio nell’anteprima di un selettore di lingua), passa l’opzione { locale } per eseguirne l’override:
---
import { useTranslations } from "@/i18n";
const tEn = useTranslations("hero", { locale: "en-US" });
---
<p>{tEn("title")}</p>
Utilizzo dei formattatori
Chiama useFormatter() per accedere ai formattatori Web Intl memorizzati nella cache e collegati al contesto locale corrente:
---
import { useFormatter } from "@/i18n";
const fmt = useFormatter();
const formattedPrice = fmt.number(129.99, { style: "currency", currency: "EUR" });
const formattedDate = fmt.dateTime(new Date(), { dateStyle: "medium" });
---
<div>
<span>{formattedPrice}</span>
<time>{formattedDate}</time>
</div>
Configurazione e utilizzo dei segmenti di percorso (Route Segments)
Si consiglia di organizzare la struttura delle pagine multilingua tramite segmenti di routing dinamici, come src/pages/[lang]/index.astro o src/pages/[locale]/about.astro.
Generazione di route statiche (SSG)
In modalità Static Site Generation (SSG), combina l’array esportato languages con getStaticPaths():
---
// src/pages/[lang]/index.astro
import { languages, useTranslations, useLocale } from "@/i18n";
export function getStaticPaths() {
return languages.map((lang) => ({
params: { lang },
}));
}
const t = useTranslations("nav");
const lang = useLocale();
---
<nav>
<a href={`/${lang}`}>{t("home")}</a>
<a href={`/${lang}/docs`}>{t("docs")}</a>
</nav>
Meccanismo di risoluzione dei segmenti di percorso
- Nomi dei parametri dei segmenti di route predefiniti: Il middleware esamina automaticamente per impostazione predefinita i parametri dinamici
context.params.langecontext.params.locale. Finché la cartella è denominata[lang]o[locale], funziona senza configurazione. - Iniezione del contesto senza props: Prima che la pagina e i suoi componenti figli vengano renderizzati, il middleware estrae il locale dal segmento di percorso e lo scrive nello scope asincrono. Qualsiasi componente figlio annidato può chiamare direttamente
useTranslations()ouseLocale()per accedere alla lingua attiva, eliminando del tutto il passaggio manuale di props dalla pagina verso i componenti figli. - Nomi personalizzati dei parametri di route: Se il progetto utilizza nomi di parametro differenti nei percorsi di routing (es.
src/pages/[localeCode]/...), configurali tramite l’opzioneparamNamesincreateAstroI18n:
export const {
/* ... */
} = createAstroI18n({
defaultLanguage: "it-IT",
paramNames: ["localeCode", "lang", "locale"],
messages: {
/* ... */
},
});
Strategia di risoluzione della lingua (Locale Resolution)
ts-intl-astro determina la lingua della richiesta secondo il seguente ordine di priorità:
context.currentLocaleintegrato di Astro (routing i18n nativo di Astro)- Parametri dinamici di routing (esamina
context.params.langecontext.params.locale, configurabile tramiteparamNames) - Analisi del prefisso del percorso URL (es. estrae il segmento iniziale come
/it-IT/...) - Fallback alla lingua predefinita (la
defaultLanguagespecificata nella configurazione)
Riferimento API
| API | Tipo | Descrizione |
|---|---|---|
createAstroI18n(config) |
Function |
Inizializza l’istanza i18n specifica per Astro; supporta defaultLanguage, messages e paramNames |
useTranslations(ns?, opts?) |
Function |
Restituisce la funzione di traduzione t associata al contesto di rendering corrente |
useLocale() |
() => string |
Restituisce il codice della lingua attiva per il contesto di rendering corrente |
useFormatter(opts?) |
() => Formatter |
Restituisce il formattatore Web Intl memorizzato nella cache e associato al contesto locale corrente |