Frameworks
Remix
Remix applications can use Messagevisor in loaders, resource routes, and client components through the React provider.
Install#
$ npm install @messagevisor/sdk @messagevisor/react @messagevisor/module-icuServer helper#
Create a server-only helper that loads all supported locale datafiles into one SDK instance:
Copy the shared datafile loader beside this helper. It checks HTTP status, retries initial failures, and retains the last known good datafiles during refresh failures.
import { createMessagevisorLoader } from "./messagevisor-loader.js";const loader = createMessagevisorLoader();export const getMessagevisor = loader.get;export const refreshMessagevisor = loader.refresh;Loaders and resource routes pass locale per call. Do not call setLocale() or setContext() while handling requests.
Loader data#
Load translated values in Remix loaders and read them with useLoaderData():
import { json, type LoaderFunctionArgs } from "@remix-run/node";import { useLoaderData } from "@remix-run/react";import { getMessagevisor } from "../messagevisor.server";export async function loader({ params, request }: LoaderFunctionArgs) { const locale = params.locale || "en-US"; const url = new URL(request.url); const plan = url.searchParams.get("plan") || undefined; const m = await getMessagevisor(); return json({ title: m.translate( "dashboard.welcome", { name: "Ada" }, { locale, context: { platform: "web", plan } } ), });}export default function DashboardRoute() { const { title } = useLoaderData<typeof loader>(); return <h1>{title}</h1>;}Resource routes#
Resource routes can return translated JSON for API-style consumers:
import { json, type LoaderFunctionArgs } from "@remix-run/node";import { getMessagevisor } from "../messagevisor.server";export async function loader({ request }: LoaderFunctionArgs) { const locale = new URL(request.url).searchParams.get("locale") || "en-US"; const m = await getMessagevisor(); return json({ message: m.translate("dashboard.welcome", { name: "Ada" }, { locale }), });}React provider hydration#
For client-side hooks, pass a loaded datafile into MessagevisorProvider:
import { useMemo } from "react";import { createMessagevisor } from "@messagevisor/sdk";import { createICUModule } from "@messagevisor/module-icu";import { MessagevisorProvider } from "@messagevisor/react";export function MessagevisorClientProvider(props: { datafile: any; children: React.ReactNode;}) { const m = useMemo( () => createMessagevisor({ datafile: props.datafile, modules: [createICUModule({ ignoreTags: false })], }), [props.datafile] ); return <MessagevisorProvider instance={m}>{props.children}</MessagevisorProvider>;}Then components below the provider can use React SDK hooks.
Client components 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. If the user switches language in the browser, load the new datafile, call setDatafile(), then call setLocale().
Loading from a CDN#
Set baseUrl when creating the shared loader:
const loader = createMessagevisorLoader({ baseUrl: "https://cdn.yoursite.com/datafiles",});The helper performs a new fetch when its cache expires or when you call its refresh() method. See explicit refresh for failure handling and deployment considerations.