Localization
Root.js has built-in localization: locale-aware URLs, translated strings, and translations for CMS content, all managed in one place.
Configuration
Set the site's locales and URL format with the i18n option in root.config.ts:
// @/root.config.ts
import {defineConfig} from '@blinkk/root';
export default defineConfig({
i18n: {
locales: ['en', 'ja'],
defaultLocale: 'en',
urlFormat: '/[locale]/[path]',
},
});
Each route is then served at a URL per locale, e.g. /ja/about. Use fallbacks to set which locales a missing translation falls back to.
Translations
Translated strings live in translations/, one JSON file per locale, mapping each source string to its translation:
// @/translations/fr.json
{
"Hello, world!": "Bonjour le monde !",
"Hello, {name}!": "Bonjour {name} !"
}
useTranslations()
useTranslations() returns a function that translates a string into the current locale. Values in curly braces are replaced with the params you pass.
// @/routes/index.tsx
import {useTranslations} from '@blinkk/root';
export default function Page(props) {
const t = useTranslations();
if (props.name) {
return <h1>{t('Hello, {name}!', {name: props.name})}</h1>;
}
return <h1>{t('Hello, world!')}</h1>;
}
Translating CMS content
Schema fields marked with translate: true are sent for translation. Editors translate them in the CMS, with AI, or by exporting them to a spreadsheet or translation vendor.
Translations are stored in the CMS, and loaded with cmsClient.loadTranslations(). Pass them to ctx.render() to use them with useTranslations(). See Data fetching.