Loading messages
Import loadMessages from the virtual module and pass its result to TranslateProvider.
The Vite plugin generates the virtual better-translation/messages module from your plugin
config. Import loadMessages from that module to load a flat lookup id map for a Locale, then
pass that map to TranslateProvider.
Everything below TranslateProvider can use the framework runtime helpers such as T, Var,
useT, or getT.
import { loadMessages, locales, type Locale } from "better-translation/messages"
const messages = await loadMessages("es")
// { "m_abc123": "Pagar ahora", ... }loadMessages has the same API in every mode. The difference is baked into the generated
virtual module by the plugin:
| Runtime config | What loadMessages(locale) does |
|---|---|
local + target: module | Imports generated JSON from your app source with Vite module imports. |
local + target: public | Fetches generated JSON from Vite public assets. |
remote | Fetches the hosted Runtime bundle for the resolved Project Branch. |
App setup
Load messages before rendering the provider so the active Locale and its Runtime bundle are available to translated content.
betterTranslation({
locales: ["en", "es", "fr"],
defaultLocale: "en",
})import { createRootRoute, Outlet } from "@tanstack/react-router"
import { loadMessages } from "better-translation/messages"
import { TranslateProvider } from "better-translation/react"
import { getLocale } from "./-locale"
export const Route = createRootRoute({
beforeLoad: async () => {
const locale = await getLocale()
const messages = await loadMessages(locale)
return { locale, messages }
},
component: RootComponent,
})
function RootComponent() {
const { locale, messages } = Route.useRouteContext()
return (
<TranslateProvider locale={locale} messages={messages}>
<Outlet />
</TranslateProvider>
)
}One config, one loader
You do not keep separate state between the Vite plugin and app runtime code. The plugin config
is the source for the generated better-translation/messages module, and your app imports
that module. Change the runtime target in vite.config.ts, restart Vite, and the generated
loader changes while your app code can keep calling loadMessages(locale).
In local development, TranslateProvider uses the active locale to apply completed
translations through Vite HMR. The authored fallback remains visible while translation is in
progress, then the translated value replaces it without a page reload or component remount.