vercel/next.js · error
Specified i18n.domains must be an array of domain objects e.
Error message
Specified i18n.domains must be an array of domain objects e.g. [ { domain: 'example.fr', defaultLocale: 'fr', locales: ['fr'] } ] received ${typeof i18n.domains}.
See more info here: https://nextjs.org/docs/messages/invalid-i18n-config What it means
Thrown when `i18n.domains` is defined but is not an array. Domains are an optional feature for serving different locales from different hostnames; the validator at config.ts:1227 only checks `typeof i18n.domains !== 'undefined' && !Array.isArray(i18n.domains)`, so `undefined` is allowed but any other non-array type fails.
Source
Thrown at packages/next/src/server/config.ts:1228
)
}
if (i18n.locales.length > 100 && !silent) {
Log.warn(
`Received ${i18n.locales.length} i18n.locales items which exceeds the recommended max of 100.\nSee more info here: https://nextjs.org/docs/advanced-features/i18n-routing#how-does-this-work-with-static-generation`
)
}
const defaultLocaleType = typeof i18n.defaultLocale
if (!i18n.defaultLocale || defaultLocaleType !== 'string') {
throw new Error(
`Specified i18n.defaultLocale should be a string.\nSee more info here: https://nextjs.org/docs/messages/invalid-i18n-config`
)
}
if (typeof i18n.domains !== 'undefined' && !Array.isArray(i18n.domains)) {
throw new Error(
`Specified i18n.domains must be an array of domain objects e.g. [ { domain: 'example.fr', defaultLocale: 'fr', locales: ['fr'] } ] received ${typeof i18n.domains}.\nSee more info here: https://nextjs.org/docs/messages/invalid-i18n-config`
)
}
if (i18n.domains) {
const invalidDomainItems = i18n.domains.filter((item) => {
if (!item || typeof item !== 'object') return true
if (!item.defaultLocale) return true
if (!item.domain || typeof item.domain !== 'string') return true
if (item.domain.includes(':')) {
console.warn(
`i18n domain: "${item.domain}" is invalid it should be a valid domain without protocol (https://) or port (:3000) e.g. example.vercel.sh`
)
return true
}
const defaultLocaleDuplicate = i18n.domains?.find(View on GitHub (pinned to 0ae8c72462)
Solutions
- Wrap domain definitions in an array: `domains: [{ domain: 'example.fr', defaultLocale: 'fr', locales: ['fr'] }]`.
- Remove the `domains` key entirely if you are not using per-domain locale routing.
Example fix
// before
module.exports = { i18n: { locales: ['fr','en'], defaultLocale: 'en', domains: { domain: 'example.fr', defaultLocale: 'fr' } } }
// after
module.exports = { i18n: { locales: ['fr','en'], defaultLocale: 'en', domains: [{ domain: 'example.fr', defaultLocale: 'fr', locales: ['fr'] }] } } Defensive patterns
Strategy: validation
Validate before calling
if (i18n.domains !== undefined && !Array.isArray(i18n.domains)) {
throw new Error('i18n.domains must be an array or undefined');
} Type guard
function hasValidDomains(i18n: any): boolean {
return i18n.domains === undefined || Array.isArray(i18n.domains);
} Prevention
- Only add `domains` when using per-hostname locale routing; otherwise omit it.
- Always wrap domain entries in an array literal.
When it happens
Trigger: Setting `i18n: { domains: { domain: 'example.fr', defaultLocale: 'fr' } }` (a single object instead of an array); `domains: 'example.fr'`; `domains: false`.
Common situations: Misreading the docs and providing a single domain object instead of a list; merging configs that overwrite the array with a scalar; converting from a YAML/JSON config that serializes a single item as an object.
Related errors
- Specified i18n.locales should be an Array received ${typeof
- Specified i18n.defaultLocale should be a string. See more in
- Specified i18n.locales must be an array of locale strings e.
- Specified i18n.localeDetection should be undefined or a bool
- Specified "i18n" cannot be used with "output: export". See m
AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06).
Data as JSON: /api/errors/e1da86306f275de8.
Report an issue: GitHub.