i18n
Model language per site in both Studio and web runtime, with validation, language-aware previews, and route-safe resolution.
Overview
Internationalisation is implemented as site-scoped language support, not a global language list. Each site declares its supported languages and primary language in packages/common/config/sites/index.ts.
That single model is reused in schema validation, editor UX, routing, and frontend data queries.
What is included
Site-specific language model
packages/common/config/sites/index.ts defines:
primaryLanguagefor fallback and default URL behaviourlanguagesavailable for that site- helpers such as
primaryLanguageFromSite(...)andvalidLanguageCodeForSite(...)
This allows the same codebase to run multilingual and single-language sites together.
Schema-level language enforcement
In apps/sanity/features/translations/schema/defineLanguageField.ts, the language field:
- offers only languages valid for the current site
- validates against
validLanguageCodeForSite(...) - can be hidden/read-only once valid values are set (configurable for editorial safety)
Document types that need localisation include this field directly (for example apps/sanity/schema/types/documents/page.ts and announcements.ts).
Translation workflows in Studio
apps/sanity/sanity.config.ts wires translation tooling:
documentInternationalization(...)for translatable document typesinternationalizedArray(...)for localised object/field values
Language is also surfaced in previews via helpers like withLanguagePreview(...), so editors can distinguish locale variants quickly.
Runtime language resolution
At request time, apps/web/src/proxy/setup-site.ts determines language by:
- checking the first URL segment (via
extractLanguageCode(...)), then - falling back to the site primary language (
primaryLanguageFromSite(...))
Routes under apps/web/src/app/(website)/~s/[siteId]/[languageCode]/... validate site/language pairs before rendering, preventing invalid combinations.
Practical outcome
- Editors can only select valid locale values per site.
- Frontend queries remain site and language scoped.
- Default-language URLs and prefixed-language URLs are handled consistently.
Last updated: 27 Apr 2026, 14:59:48
Deep Structure Integration and Helpers
Use site/language-aware structure helpers to build cleaner Sanity desk structures with consistent filters, intents, and template wiring.
Initial Value Templates
Automatically prefill `site` and `language` on new documents, using static and dynamic templates tuned for multisite and multilingual workflows.
