Nuxt
Nuxt applications can use Messagevisor in server-rendered pages, Nitro API routes, and client-side plugins.
Install#
$ npm install @messagevisor/sdk @messagevisor/vue @messagevisor/module-icuServer utility#
Create a server-only loader that reads all supported locale datafiles into one SDK instance:
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((datafiles) => { const m = createMessagevisor({ datafile: datafiles[0], modules: [createICUModule({ ignoreTags: false })], }); datafiles.slice(1).forEach((datafile) => m.setDatafile(datafile)); return m; }); return instancePromise;}Nitro API routes pass locale per call. Do not call setLocale() or setContext() while handling requests.
Server-rendered page#
Nuxt pages can call a server API route during SSR and reuse the result on the client:
<script setup lang="ts">const route = useRoute();const locale = String(route.params.locale || "en-US");const { data } = await useAsyncData(`welcome-${locale}`, () => $fetch("/api/welcome", { query: { locale, plan: "pro", }, }));</script><template> <h1>{{ data?.message }}</h1></template>API routes#
Nitro server routes can return translated JSON:
export default defineEventHandler(async (event) => { const query = getQuery(event); const locale = String(query.locale || "en-US"); const plan = typeof query.plan === "string" ? query.plan : undefined; const m = await getMessagevisor(); return { message: m.translate( "dashboard.welcome", { name: "Ada" }, { locale, context: { platform: "web", plan } } ), };});Client plugin#
For browser-side evaluation, serve built datafiles from public/datafiles and create a Nuxt plugin. The browser has one active user, so keep locale at instance level:
import { createMessagevisor } from "@messagevisor/sdk";import { createICUModule } from "@messagevisor/module-icu";import { createMessagevisorProvider } from "@messagevisor/vue";export default defineNuxtPlugin(async (nuxtApp) => { const locale = "en-US"; const datafile = await $fetch(`/datafiles/messagevisor-web-${locale}.json`); const m = createMessagevisor({ datafile, locale, modules: [createICUModule({ ignoreTags: false })], }); nuxtApp.vueApp.use(createMessagevisorProvider({ instance: m })); return { provide: { messagevisor: m, }, };});Then use the injected instance in components:
<script setup lang="ts">const { $messagevisor } = useNuxtApp();const label = $messagevisor.translate("auth.signin");</script><template> <button>{{ label }}</button></template>Or use the Vue package composables directly:
<script setup lang="ts">import { useTranslation } from "@messagevisor/vue";const label = useTranslation("auth.signin");</script><template> <button>{{ label }}</button></template>If the user can switch locales in the browser, fetch the new datafile, call setDatafile(), then call setLocale().
Browser-side components do not need to pass locale per call. The plugin instance represents the current user's active locale.
Loading from a CDN#
If datafiles are published under a different path, update the CDN URL in your server utility or the browser plugin's public URL:
const datafile = await fetch( `https://cdn.yoursite.com/datafiles/messagevisor-web-${locale}.json`).then((response) => response.json());
