Vize

i18n

Declare typed message catalogs for several locales.

Package @vizejs/composable/i18n
Own the source vize lib pull composable:i18n
Runtime exports defineMessages, defineLocale, defineI18n, useI18n
Gzip budget 7168 B

Usage

import { defineMessages, defineLocale, defineI18n, useI18n } from "@vizejs/composable/i18n";

Runtime contract

Utility Category Stability SSR Hydration Cleanup Targets Host globals Uses
defineMessages i18n experimental safe stable none web, server, worker, native, desktop, terminal — —
defineLocale i18n experimental safe stable none web, server, worker, native, desktop, terminal — —
defineI18n i18n experimental safe stable returned-value web, server, worker, native, desktop, terminal Intl createMessageFormatter, useLocale
useI18n i18n experimental safe stable none web, server, worker, native, desktop, terminal — —

API

defineMessages

Declare typed message catalogs for several locales. The literal messages are preserved, so MessageParamsFor knows the ICU parameters of every key. The compiler rejects catalogs whose locales do not share the same keys (__missingTranslations) or whose translations need incompatible parameter types (__incompatibleParams). Returns the catalogs unchanged; the function exists for inference and validation only.

function defineMessages<const Catalogs extends MessageCatalogs>( catalogs: Catalogs & ValidateCatalogs<Catalogs>, ): Catalogs
const messages = defineMessages({
  en: { cart: "{count, plural, one {# item} other {# items}}" },
  ja: { cart: "{count, plural, other {# 個}}" },
});

defineLocale

Declare one additional locale (typically a lazily loaded module) against the catalogs produced by defineMessages. The keys must match exactly, and every translation may only use parameters the schema declares, with compatible types.

function defineLocale<Catalogs extends MessageCatalogs>(): < const Tree extends LocaleMessages<Catalogs>, >( catalog: Tree & ValidateTranslation<Catalogs, Tree>, ) => Tree
// fr.ts
export default defineLocale<typeof messages>()({ cart: "{count, plural, one {# article} other {# articles}}" });

defineI18n

Define the typed i18n setup of an application. The definition holds only static configuration (catalogs, loaders, formats) and an injection key; it has no mutable module state. Call create() per request on the server and once on the client, install the instance with app.use(instance), and read it in components with definition.use() (or useI18n). Locale changes are reactive through setLocale, which loads lazy locales first; Intl formatting follows the locale through the existing useLocale composable. Hydration: locale detection is never automatic. Resolve the locale per request, pass it to create({ locale }) on both sides, and await instance.ready before rendering or mounting when it is lazy. date/time arguments use a fixed time zone (UTC unless configured).

function defineI18n< const Catalogs extends MessageCatalogs, const Lazy extends string = never, >(options: DefineI18nOptions<Catalogs, Lazy>): I18nDefinition<Catalogs, Lazy>
export const appI18n = defineI18n({
  messages,
  loaders: { fr: () => import("./locales/fr.ts") },
});
// per request / client entry
const i18n = appI18n.create({ locale: "fr" });
await i18n.ready;
app.use(i18n);
// component
const { t } = appI18n.use();
t("cart", { count: 2 });

useI18n

Inject the i18n instance of a definition. Equivalent to definition.use(); must run inside setup (or app.runWithContext).

function useI18n<Catalogs extends MessageCatalogs, Lazy extends string>( definition: I18nDefinition<Catalogs, Lazy>, ): I18n<Catalogs, Lazy>
const { t, setLocale } = useI18n(appI18n);

Types

DefineI18nOptions

Static configuration shared by every request, passed to defineI18n.

Member Type Description
timeZone? string IANA time zone for date and time arguments. Fixed by default so server and client render identically.
numberFormats? Readonly<Record<string, Intl.NumberFormatOptions>> Named number styles usable as {n, number, name}.
dateTimeFormats? Readonly<Record<string, Intl.DateTimeFormatOptions>> Named date/time styles usable as {d, date, name}.
messages Catalogs Eagerly bundled catalogs (see defineMessages).
fallbackLocale? keyof Catalogs & string Locale used when a key is missing in the active locale.
loaders? { readonly [Locale in Lazy]: LocaleLoader<Catalogs> } Loaders for locales fetched on demand.
onMissing? (key: string, locale: string) => void Called when a key is missing in the active and fallback locales; the key itself is rendered.

I18n

Per-request i18n state and typed translation functions.

Member Type Description
locale Readonly<ShallowRef<(keyof Catalogs & string) | Lazy>> Active locale. Change it with I18n.setLocale.
availableLocales readonly ((keyof Catalogs & string) | Lazy)[] Every locale this instance can switch to.
loadedLocales ComputedRef<((keyof Catalogs & string) | Lazy)[]> Locales whose messages are available right now.
isLoading Readonly<ShallowRef<boolean>> Whether a lazy locale is being loaded.
error Readonly<ShallowRef<unknown>> Most recent loader failure, cleared on success.
direction ComputedRef<TextDirection> Text direction of the active locale.
intl LocaleControls Intl helpers bound to the active locale (from useLocale).
ready Promise<void> Resolves once the initial locale's messages are loaded.
t <Key extends MessageKey<Catalogs> & string>( key: Key, ...params: TranslateArguments<MessageParamsFor<Catalogs, Key>> ) => string Translate a key. Parameters are typed from the ICU messages of every locale. Reactive: reading inside a render re-renders on locale change.
te (key: MessageKey<Catalogs> & string) => boolean Whether key exists in the active locale.
setLocale (locale: (keyof Catalogs & string) | Lazy) => Promise<void> Load (if needed) and activate a locale.
loadLocale (locale: (keyof Catalogs & string) | Lazy) => Promise<void> Load a lazy locale without activating it (for example on hover).
install (app: App) => void Vue plugin hook: provides this instance to the app.

CreateI18nOptions

Options for I18nDefinition.create.

Member Type Description
locale? Locale Initial locale. Pass the locale resolved for the request (server) and the same value on the client so hydration renders identical text.

I18nDefinition

Static i18n definition returned by defineI18n.

Member Type Description
key InjectionKey<I18n<Catalogs, Lazy>> Injection key under which instances are provided.
create ( options?: CreateI18nOptions<(keyof Catalogs & string) | Lazy>, ) => I18n<Catalogs, Lazy> Create a per-request (per-app) instance. Never share one instance between server requests.
use () => I18n<Catalogs, Lazy> Inject the instance provided by an ancestor (or app.use(instance)).