Skip to main content
Framework

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:

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:

json
// @/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.

tsx
// @/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.

1
2
3
4
5
6
7
8
9
10
11
12
Breakpoint: