Internationalization
A special [locale] route segment, plus t("key") in the body, seo and schema — resolved against src/locales/<locale>.json. This very tutorial you're reading uses exactly this mechanism.
The [locale] segment
src/pages/[locale]/index.tsx -> /es, /en, ...pages/[locale]/index.tsx is served at /es, /en, or any locale you have under src/locales/.
Translating with t()
// src/locales/en.json
{ "home": { "title": "Welcome to Nexa" } }
// src/pages/[locale]/index.tsx
export default function Home() {
return <h1>{t("home.title")}</h1>;
}t("key") recognizes one exact syntactic pattern: an identifier t with a single string literal — no dynamic key (t(variable) isn't recognized).
Automatic hreflang
<link rel="alternate" hreflang="es" href="/es">
<link rel="alternate" hreflang="en" href="/en">When more than one locale is available, Nexa generates the <link rel="alternate" hreflang="..."> for every translation automatically.
Interpolation: t("key", { variable })
// src/locales/<locale>.json
{ "profile": { "donateTo": "Support {name}" } }
<p>{t("profile.donateTo", { name: data.creatorName })}</p>The second argument substitutes each variable placeholder in the text (see the example below) with a data.x/params.x reference — the same limited reference any other dynamic position in Nexa accepts, never a literal or an arbitrary expression. nexa build/nexa lint fail with a clear error if a key and its arguments don't match (a placeholder with no variable, or a leftover variable) — a broken, explicit build beats an unresolved placeholder shipped to production.