How it works
How the Vite plugin discovers Messages, keeps Locale values in sync, and generates runtime loaders.
The Vite plugin scans your source for Translation markers at build time, gives each Message a stable lookup id, and keeps your Locale values in sync. At runtime your app loads a flat map of translated strings for the active Locale, so your components keep rendering normal UI.
1. Mark
Wrap copy in a Translation marker where you author it. No keys to invent.
2. Discover
The plugin discovers Messages and builds a Manifest keyed by stable lookup id.
3. Fill Locale values
Local mode writes Runtime bundles in your repo. Remote mode syncs the Manifest to the platform.
4. Load
Your app loads flat Runtime bundles by Locale. No Manifest metadata reaches the browser.
Source discovery
Better Translation looks for markers such as T, useT, getT, and t() inside your
configured source roots. Each discovered Message records the Default locale text,
Variable placeholders, optional context, and durable source references in the private Manifest.
The lookup id is stable, so moving a Message through the codebase does not create a new runtime key. If two Messages need different translations, add context or an explicit id to separate them.
When a T Message contains a supported inline element or source-owned component, the plugin
represents that authored renderer with a numbered Rich-text slot such as <0>...</0> or <1/>. The
numbered form is the Message translators see; component implementations, props, events, and
bindings remain in source code.
Locale values
The Manifest is source metadata. Locale values are the translated strings for each configured Locale. In local mode, the plugin writes those values into generated JSON files in your app. In remote mode, the plugin syncs the Manifest to a hosted Project and the platform stores branch-local Locale values.
Local translation is an optional local-mode convenience. The translate function receives the
missing Messages for a target Locale and returns a lookup id to translated string map. Remote
mode does not use that package-local function; it uses the Platform translator.
Runtime loading
Your app imports loadMessages from the virtual better-translation/messages module. The
plugin generates that module from your runtime mode:
| Runtime config | Loader behavior |
|---|---|
local + target: module | Imports generated Locale JSON through Vite. |
local + target: public | Fetches generated Locale JSON from Vite public assets. |
remote | Fetches hosted Runtime bundles for the resolved Project Branch. |
Every loader returns the same shape: a flat lookup id to translated string object. Runtime bundles do not contain Manifest metadata, source ownership, editor state, or write credentials.
Rich-text Locale values are still strings. React and Svelte render numbered slots through the
elements and components authored in the original T marker; they never turn a translated
value into arbitrary HTML. The runtime verifies that a translated value preserves the source
variables and numbered-tag topology. If it does not, T renders the authored source content
instead.
One runtime API
Your app still calls loadMessages(locale) in every mode. The Vite plugin owns the difference between local files, public
files, and hosted Runtime bundles.