Astro: Using Islands
One Astro page can host multiple Lingui integrations
Section titled “One Astro page can host multiple Lingui integrations”An Astro app often contains three different authoring surfaces at once:
.astropages and layouts- Svelte islands
- React islands
They should not all use the same package.
Recommended split
Section titled “Recommended split”- Use
lingui-for-astrofor.astrofiles. - Use
lingui-for-svelteinside Svelte islands. - Use official Lingui packages inside React islands.
This split matches how each renderer actually executes.
Why the split matters
Section titled “Why the split matters”Astro pages usually render to static HTML, or become request-bound only when you opt into
server or hybrid output. Svelte and React islands keep their own component runtime and
hydration model. Trying to force one runtime API across all three makes the authoring model worse,
not better.
Shared pieces
Section titled “Shared pieces”The pieces that can be shared safely are:
- catalogs
- locale selection logic
- plain TypeScript message descriptors
The translation call site should still use the package that matches the current renderer.
Practical pattern
Section titled “Practical pattern”- Resolve the active locale at the Astro app boundary (middleware or frontmatter).
- Load the correct catalogs for the page render.
- Render
.astrowithlingui-for-astro. - Pass
localeinto each island as a prop. - Inside each island, call
setLinguiContextwith that locale.
---import { t } from "lingui-for-astro/macro";import MyIsland from "../components/MyIsland.svelte";
// locale is set in middleware via setLinguiContextconst locale = Astro.locals.lingui?.i18n.locale ?? "en";---
<h1>{t`Welcome`}</h1>
<!-- Pass locale so the island uses the same locale as the page. --><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>Pass locale from the page, not translated strings, so the island can translate its own messages
using the same locale, and react to future locale changes if needed.