Internationalization
The starter ships English-only out of the box, but the i18n engine is fully wired so you can add languages without re-architecting anything.
How It Works
Section titled “How It Works”The i18n system is built on three layers:
- Astro’s built-in i18n — locale routing configured in
astro.config.ts - Content collection locale fields — each content entry declares its
locale - Translation files — UI strings live in
src/i18n/<locale>.json
The single source of truth for active locales is src/config/i18n.config.ts
(mirrored in src/lib/site-config.ts and astro.config.ts).
UI Translations
Section titled “UI Translations”UI strings live in src/i18n/en.json and are read through the t() helper:
---import { t } from "../i18n/ui";const locale = (Astro.currentLocale || "en") as "en";---<p>{t(locale, "nav.home")}</p>t() falls back to the key itself when a string is missing, so dev builds fail
loudly when a translation is absent.
Adding a New Locale
Section titled “Adding a New Locale”-
Widen the type in
src/lib/site-config.ts:export type Locale = "en" | "id"; -
Register the locale in the config files:
src/lib/site-config.ts locales: ["en", "id"] as const,localeLabels: { en: "English", id: "Indonesia" } as const,localePrefixes: { en: "en", id: "id" } as const,// src/config/i18n.config.ts → locales: ["en", "id"]// astro.config.ts → i18n.locales + sitemap.i18n.locales -
Add a translations file
src/i18n/id.jsonand register it insrc/i18n/ui.ts:import id from "./id.json";export const translations = { en, id }; -
Add localized content by setting the
localefrontmatter on a copy of each entry (e.g.about.mdforen,about.id.mdforid), and extend thelocaleenum insrc/content.config.ts. -
Add prefixed routes under
src/pages/[locale]/for the non-default locales (the default locale is served at the root with no prefix).
Once a second locale is registered, the header language switcher shows up automatically.