Astro: アイランドの使用
1 つの Astro ページに複数の Lingui 統合を共存させられる
セクションタイトル “1 つの Astro ページに複数の Lingui 統合を共存させられる”Astro アプリには、同時に次の 3 つの記述面が存在することがよくあります。
.astroページとレイアウト- Svelte アイランド
- React アイランド
これらすべてで同じパッケージを使うべきではありません。
推奨される分担
セクションタイトル “推奨される分担”.astroファイルではlingui-for-astroを使います- Svelte アイランド内では
lingui-for-svelteを使います - React アイランド内では Lingui 公式パッケージを使います
この分担は、各描画系が実際にどう実行されるかに対応しています。
なぜこの分担が重要か
セクションタイトル “なぜこの分担が重要か”Astro ページは通常、静的 HTML として描画されるか、server / hybrid 出力を選んだときだけリクエスト依存になります。
一方、Svelte と React のアイランドは、それぞれ独自のコンポーネント実行時とハイドレーションモデルを持っています。
この 3 つに対して 1 つの実行時 API を無理に共通化しようとすると、使い勝手は良くなるどころか悪化します。
共有できるもの
セクションタイトル “共有できるもの”安全に共有できるのは次のものです。
- カタログ
- ロケール選択ロジック
- 素の TypeScript で定義したメッセージ記述子
それでも、翻訳を呼び出す箇所では現在の描画系に合ったパッケージを使うべきです。
実用的なパターン
セクションタイトル “実用的なパターン”- Astro アプリの境界(ミドルウェアまたはフロントマター)で有効なロケールを解決します。
- ページ描画に必要な正しいカタログを読み込みます。
.astroはlingui-for-astroで描画します。- 各アイランドへ
localeをプロパティとして渡します。 - 各アイランドの内部で、そのロケールを使って
setLinguiContextを呼びます。
---import { t } from "lingui-for-astro/macro";import { getLinguiContext } from "lingui-for-astro";import MyIsland from "../components/MyIsland.svelte";
// ロケールはミドルウェア内の setLinguiContext で設定済みconst locale = getLinguiContext(Astro.locals).i18n.locale;---
<h1>{t`Welcome`}</h1>
<!-- ページと同じロケールをアイランドでも使うように渡す。 --><MyIsland client:load {locale} /><script lang="ts"> import { untrack } from "svelte"; import { setupI18n } from "@lingui/core"; import { setLinguiContext } from "lingui-for-svelte"; import { t } from "lingui-for-svelte/macro"; import { catalog } from "$lib/i18n/catalog";
const { locale = "en" } = $props();
const i18n = setupI18n({ locale: untrack(() => locale), messages: catalog }); setLinguiContext(i18n);</script>
<p>{$t`Hello from a Svelte island`}</p>アイランドには翻訳済み文字列ではなく locale を渡してください。
そうすれば、アイランド自身が同じロケールでメッセージを翻訳でき、必要なら将来のロケール変更にも追従できます。