Translating Pages
Render localized strings with use-intl, declare route namespaces, and load translation bundles.
VitNode uses use-intl for frontend translations. To keep initial payloads small, pages only download the translation namespaces they explicitly declare.
Quick start
1. In a Plugin Route (Recommended)
Plugin routes declare namespaces in routes/manifest.ts. VitNode loads the strings in parallel with the route chunk automatically:
export const routes: PluginRouteDefinition[] = [
{
entry: "routes/about-page",
id: "about",
path: "/blog/about",
namespaces: ["@vitnode/blog.about"],
},
]Read strings directly with useTranslations:
import { useTranslations } from "use-intl"
const AboutPage = () => {
const t = useTranslations("@vitnode/blog.about")
return <h1>{t("title")}</h1>
}
export default AboutPageAnd define the messages in plugins/blog/src/locales/en.json:
{
"@vitnode/blog": {
"about": {
"title": "About Our Blog"
}
}
}2. In an Application Route File
For host app routes, warm the translation query in your loader and wrap the component in <RouteMessages>:
import { createFileRoute } from "@tanstack/react-router"
import { intlQueryOptions, RouteMessages } from "@vitnode/core/tanstack/i18n"
import { useTranslations } from "use-intl"
const ABOUT_NAMESPACES = ["core.global", "app.about"]
export const Route = createFileRoute("/_main/about")({
loader: async ({ context }) =>
await context.queryClient.ensureQueryData(
intlQueryOptions({
locale: context.locale,
namespaces: ABOUT_NAMESPACES,
}),
),
component: AboutRoute,
})
function AboutRoute() {
return (
<RouteMessages namespaces={ABOUT_NAMESPACES}>
<AboutContent />
</RouteMessages>
)
}
function AboutContent() {
const t = useTranslations("app.about")
return <h1>{t("title")}</h1>
}Placeholders and Pluralization
VitNode supports ICU message syntax out of the box:
{
"cart": {
"greeting": "Hello, {name}!",
"items": "{count, plural, =0 {No items} one {1 item} other {# items}}"
}
}In your React component:
const t = useTranslations("cart")
return (
<div>
<p>{t("greeting", { name: "Alex" })}</p>
<p>{t("items", { count: 3 })}</p>
</div>
)Global namespaces
core.global is provided by the root shell to every route, supplying shared strings for dialogs, toasts, and buttons.