Base Config
Everything lives in i18n inside pages/+config.ts.
// +config
type I18nConfig = {
defaultLocale: string
locales: string[] | Record<string, { urlPrefix: string; meta?: Record<string, any> }>
routes: Record<string, Record<string, string> | I18nRoutes>
prefixDefaultLocale?: boolean
domains?: Record<string, DomainConfig>
domainDetector?: (pageContext) => string | null | undefined
localeDetector?:
| ((pageContext) => string | null | undefined)
| {
acceptLanguageHeader?: boolean
localeCookie?: boolean
queryParams?: boolean
session?: boolean
}
debug?: boolean
localeCookie?: string | false
}locales
Simple form — locale code is also used as the URL prefix:
// +config
locales: ['en', 'ru', 'fr']Object form — use when the URL prefix should differ from the locale code:
// +config
locales: {
en: { urlPrefix: 'en' },
'zh-Hans': { urlPrefix: 'zh' }, // /zh/... instead of /zh-Hans/...
}Locale entries can also carry arbitrary metadata:
// +config
locales: {
en: { urlPrefix: 'en', meta: { currency: 'USD', region: 'us' } },
de: { urlPrefix: 'de', meta: { currency: 'EUR', region: 'de' } },
}routes
routes maps canonical route keys to localized public paths. See I18n Routes for full details.
// +config
routes: {
'/about': { en: '/about', ru: '/o-nas' },
}The key on the left is what your app works with internally.
You can also group related routes by canonical prefix:
// +config
routes: {
'/blog': {
'/:slug': { en: '/:slug', ru: '/:slug' },
'/category/:category': {
en: '/category/:category',
ru: '/kategoriya/:category',
},
},
}Grouped route values are relative to the group prefix, so /blog + /:slug becomes the canonical route /blog/:slug.
prefixDefaultLocale
When true:
// +config
prefixDefaultLocale: true/aboutredirects to/en/about/en/aboutstays prefixed
When false:
// +config
prefixDefaultLocale: false/aboutstays/about/en/aboutredirects to/about
Minimal config
// +config
i18n: {
defaultLocale: 'en',
locales: ['en', 'ru'],
routes: {
'/': { en: '/', ru: '/' },
'/about': { en: '/about', ru: '/o-nas' },
},
}Optional base settings
// +config
i18n: {
localeCookie: 'locale',
localeDetector(pageContext) {
return pageContext.session?.locale
},
}Built-in locale detection sources can also be toggled without replacing the detector:
// +config
i18n: {
localeCookie: 'locale',
localeDetector: {
acceptLanguageHeader: false,
localeCookie: false,
queryParams: false,
session: true,
},
}Enable locale negotiation logs during development:
// +config
i18n: {
debug: true,
}By default, locale negotiation logging is enabled on the dev server. Set debug: false to silence it.
When localeDetector is a function, the built-in detection sources still run after it unless it returns a valid locale code.
Next: Getting Current Locale