Localization
Create locale-aware messages, detection, document direction, and localized application links.
Use one application i18n service
createI18n owns supported locales, nested messages, the current locale, and optional locale prefixes. Creating src/i18n.ts alone does not run it: import the service from your browser entry before bootTavo and supply it as ssr.i18n in tavo.config.ts. Both environments must initialize the same catalog so SSR, hydration, links, and later navigation agree.
Define locales and messages together
The default locale is also the fallback unless you configure another. Locale detection can use the path, cookie, and Accept-Language header.
tsimport { createI18n } from "@tavojs/core";
export const i18n = createI18n({
defaultLocale: "en",
routing: { enabled: true },
locales: {
en: { label: "English", dir: "ltr" },
es: { label: "Español", dir: "ltr" }
},
messages: {
en: { projects: { title: "Projects" } },
es: { projects: { title: "Proyectos" } }
}
});Initialize the service in both entry points
Merge these lines into the existing configuration and browser entry. Creating the service registers it as tavo:i18n, which Link discovers; passing it to ssr.i18n also makes the server setup explicit.
tsimport { defineConfig } from "@tavojs/core/config";
import { i18n } from "./src/i18n";
export default defineConfig({
ssr: { i18n }
});tsximport "./i18n";
import { bootTavo } from "@tavojs/core";
void bootTavo();tsximport { i18n } from "../i18n";
export default function ProjectsPage() {
return <main><h1>{i18n.t("projects.title")}</h1></main>;
}Keep server and browser locale state aligned
Resolve the request locale before rendering route loaders and metadata.
Use the
Tavo.jsLinkintegration so internal destinations receive the active locale prefix.Set document language and direction from the resolved locale.
Do not read a browser-only locale during the first render of an SSR page.
Localization options and defaults
locale and
fallbackLocaledefault todefaultLocale. Direction defaults to ltr.The locale cookie defaults to tavo_locale and detection order defaults to path, cookie, then Accept-Language.
The default locale has no URL prefix unless
defaultLocalePrefixis always orlocalizePathrequestsincludeDefaultLocale.The service registers as
tavo:i18n by default soLinkand the pages runtime can discover it. SetserviceName: false to avoid registration.
tscreateI18n({
defaultLocale,
locale?,
fallbackLocale?,
messages,
locales?: { [locale]: { label?: string; dir?: "ltr" | "rtl" | "auto" } },
routing?: false | {
enabled?: boolean;
defaultLocalePrefix?: "always" | "never";
cookieName?: string;
detectFrom?: Array<"path" | "cookie" | "header">;
},
serviceName?: string | false,
onMissingKey?: ({ key, locale, fallbackLocale }) => string | void
});Localization service reference
text and t are reactive when read during component rendering. t interpolates string parameters and stringifies non-string leaf values.
setLocalepersists by default when cookie detection is enabled; pass persist: false for a temporary selection.A missing key uses
onMissingKeywhen supplied and otherwise returns the key itself.defineMessagesmarks the central catalog for build-time locale splitting. Generated locale chunks are applied automatically by the framework runtime.
tsi18n.locale; i18n.defaultLocale; i18n.fallbackLocale; i18n.locales; i18n.dir;
i18n.messages; i18n.text; i18n.store;
i18n.setLocale(locale, { persist?: boolean });
i18n.setMessages(locale, messages, { merge?: boolean });
i18n.getLocaleInfo(locale?);
i18n.detectLocale({ pathname?, request?, headers?, cookie? });
i18n.resolvePath(pathname);
i18n.localizePath(pathname, locale?, { includeDefaultLocale?: boolean });
i18n.setLocaleFromRequest(input?); i18n.setLocaleFromPath(pathname);
i18n["t"](key, params?);
i18n.subscribe(listener, { immediate?: boolean });
i18n.watchLocale(listener, { immediate?: boolean });Look up exact public types
Follow linked API names to their canonical TypeScript declarations and package boundaries.