Astro-Integration (ts-intl-astro)
ts-intl-astro ist ein Integrationspaket für Astro, das auf der Kernbibliothek @aaakul/ts-intl aufbaut. Durch die Verwaltung des Sprachstatus der Anfrage über asynchronen Kontext (AsyncLocalStorage) entfällt die Notwendigkeit, Sprach-Props durch den gesamten Komponentenbaum nach unten durchzureichen (Prop-Drilling).
Hauptmerkmale
- Kein Prop-Drilling: Dank
AsyncLocalStorageund Astro-Middleware in Node.js sowie modernen Laufzeitumgebungen kann jede Komponente direktuseTranslations()aufrufen, um auf die Übersetzungsfunktionen für die aktive Sprache der Anfrage zuzugreifen. - Automatische Middleware-Injektion: Die Registrierung der Integration in
astro.config.mjsinjiziert automatisch eine Pre-Middleware in Astros Render-Pipeline, um das aktive Seiten-Locale aufzulösen. Unterstütztcontext.currentLocale, Routenparameter ([lang],[locale]) und URL-Pfadanalysen. - Strikte Typsicherheit: Übernimmt die vollständige Typinferenz zur Kompilierzeit von
ts-intl, einschließlich Namespace-Beschränkungen, Schlüssel-Autovervollständigung, ICU-Parametervalidierung und Paritätsprüfungen für mehrsprachige Wörterbücher.
Installation
Installieren Sie ts-intl-astro und seine Abhängigkeiten in Ihrem Astro-Projekt:
pnpm add ts-intl-astro
# oder
npm install ts-intl-astro
# oder
yarn add ts-intl-astro
Schnelleinrichtung
1. i18n-Instanz initialisieren
Erstellen und exportieren Sie Übersetzungshooks und die Instanzkonfiguration in src/i18n/index.ts:
// src/i18n/index.ts
import { createAstroI18n } from "ts-intl-astro";
import deDE from "./messages/de-DE";
import enUS from "./messages/en-US";
export const {
useTranslations,
useLocale,
useFormatter,
languages,
defaultLanguage,
} = createAstroI18n({
defaultLanguage: "de-DE",
messages: {
"de-DE": deDE,
"en-US": enUS,
},
});
export type SupportedLanguage = (typeof languages)[number];
2. Astro-Integration registrieren
Importieren und aktivieren Sie tsIntl in Ihrer astro.config.mjs:
// astro.config.mjs
import { defineConfig } from "astro/config";
import tsIntl from "ts-intl-astro";
export default defineConfig({
integrations: [tsIntl()],
});
Die Integration registriert automatisch eine Kontext-Middleware während des Astro-Builds und zur Laufzeit. Wenn eine Seite eine Anfrage verarbeitet oder statische Seiten generiert werden, löst die Middleware das Routen-Locale auf und injiziert den aktiven Kontext in den Request-Scope.
Verwendung in Komponenten
Wenn die Kontext-Middleware aktiv ist, müssen Komponenten keine lang-Prop mehr deklarieren oder entgegennehmen:
Grundlegende Verwendung
---
// 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>
Explizites Überschreiben des Locales
Wenn eine isolierte Komponente in einem bestimmten Locale gerendert werden muss (beispielsweise in der Vorschau eines Sprachumschalters), übergeben Sie die Option { locale }:
---
import { useTranslations } from "@/i18n";
const tEn = useTranslations("hero", { locale: "en-US" });
---
<p>{tEn("title")}</p>
Verwendung von Formatierern
Rufen Sie useFormatter() auf, um auf gecachte Web-Intl-Formatierer zuzugreifen, die an den aktuellen Locale-Kontext gebunden sind:
---
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>
Konfiguration und Verwendung von Routensegmenten (Route Segments)
Es wird empfohlen, mehrsprachige Seitenstrukturen mithilfe dynamischer Routensegmente zu organisieren, wie etwa src/pages/[lang]/index.astro oder src/pages/[locale]/about.astro.
Statische Routengenerierung (SSG)
Kombinieren Sie im SSG-Modus (Static Site Generation) das exportierte languages-Array mit 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>
Auflösungsmechanismus für Routensegmente
- Standard-Parameternamen für Routensegmente: Die Middleware prüft standardmäßig automatisch die dynamischen Routenparameter
context.params.langundcontext.params.locale. Sofern Ihr Verzeichnis[lang]oder[locale]heißt, funktioniert dies völlig ohne Konfiguration. - Kontext-Injektion ohne Props: Bevor die Seite und ihre untergeordneten Komponenten gerendert werden, extrahiert die Middleware das Locale aus dem Routensegment und hinterlegt es im asynchronen Scope. Alle verschachtelten Kindkomponenten können direkt
useTranslations()oderuseLocale()aufrufen, um auf das aktive Locale zuzugreifen – Prop-Drilling von der Seite hinab zu Kindkomponenten entfällt vollständig. - Benutzerdefinierte Routenparameternamen: Falls Ihr Projekt andere Parameternamen in den Routenpfaden verwendet (z. B.
src/pages/[localeCode]/...), konfigurieren Sie diese über die OptionparamNamesincreateAstroI18n:
export const {
/* ... */
} = createAstroI18n({
defaultLanguage: "de-DE",
paramNames: ["localeCode", "lang", "locale"],
messages: {
/* ... */
},
});
Strategie zur Locale-Auflösung
ts-intl-astro löst das angeforderte Locale anhand der folgenden Prioritätsreihenfolge auf:
- Astros integriertes
context.currentLocale(natives i18n-Routing von Astro) - Dynamische Routenparameter (prüft
context.params.langundcontext.params.locale, konfigurierbar überparamNames) - URL-Pfadpräfix-Analyse (extrahiert z. B. das führende Segment wie
/de-DE/...) - Fallback auf die Standardsprache (das in der Konfiguration festgelegte
defaultLanguage)
API-Referenz
| API | Typ | Beschreibung |
|---|---|---|
createAstroI18n(config) |
Function |
Initialisiert eine Astro-spezifische i18n-Instanz; unterstützt defaultLanguage, messages und paramNames |
useTranslations(ns?, opts?) |
Function |
Gibt die an den aktuellen Rendering-Kontext gebundene Übersetzerfunktion t zurück |
useLocale() |
() => string |
Gibt den aktiven Sprachcode für den aktuellen Rendering-Kontext zurück |
useFormatter(opts?) |
() => Formatter |
Gibt den gecachten Web-Intl-Formatierer gebunden an den aktuellen Locale-Kontext zurück |