Astro
Astro can use Messagevisor during server rendering, static generation, or inside hydrated client islands.
Install#
Command
$ npm install @messagevisor/sdk @messagevisor/module-icuFor React islands, also install:
Command
$ npm install @messagevisor/reactLoad one server SDK instance#
src/messagevisor.ts
import { createMessagevisor, type Messagevisor } from "@messagevisor/sdk";import { createICUModule } from "@messagevisor/module-icu";const supportedLocales = ["en-US", "nl-NL"];let instancePromise: Promise<Messagevisor> | undefined;export async function getMessagevisor() { if (instancePromise) return instancePromise; instancePromise = Promise.all( supportedLocales.map((locale) => fetch(`https://cdn.yoursite.com/datafiles/messagevisor-web-${locale}.json`).then( (response) => response.json() ) ) ).then((datafiles) => { const m = createMessagevisor({ datafile: datafiles[0], modules: [createICUModule({ ignoreTags: false })], }); datafiles.slice(1).forEach((datafile) => m.setDatafile(datafile)); return m; }); return instancePromise;}Server-rendered pages pass locale per call. Do not call setLocale() or setContext() while handling requests.
Server-rendered page#
src/pages/[locale]/index.astro
---import { getMessagevisor } from "../../messagevisor";const { locale = "en-US" } = Astro.params;const m = await getMessagevisor();const title = m.translate( "dashboard.welcome", { name: "Ada" }, { locale, context: { platform: "web" } });---<h1>{title}</h1>Client islands#
If a React island needs reactive translation hooks, pass the datafile into a React provider inside the island. The island follows the same pattern as React SDK.
src/components/TranslatedIsland.tsx
import { useMemo } from "react";import { createMessagevisor } from "@messagevisor/sdk";import { createICUModule } from "@messagevisor/module-icu";import { MessagevisorProvider, useTranslation } from "@messagevisor/react";function Greeting() { return <p>{useTranslation("dashboard.welcome", { name: "Ada" })}</p>;}export function TranslatedIsland({ datafile }: { datafile: any }) { const m = useMemo( () => createMessagevisor({ datafile, modules: [createICUModule()] }), [datafile] ); return ( <MessagevisorProvider instance={m}> <Greeting /> </MessagevisorProvider> );}Client islands do not need to pass locale per call. They receive one datafile for the current user-facing locale, and the provider instance keeps that locale as its active locale.
Context and locale#
Astro pages often know locale from the route and context from cookies, headers, or frontmatter. Pass request-specific context per evaluation:
m.translate("billing.upgrade", undefined, { locale, context: { platform: "web", plan: Astro.cookies.get("plan")?.value, },});
