{"record":{"id":"e1da86306f275de8","repo":"vercel/next.js","slug":"specified-i18n-domains-must-be-an-array-of-domain","errorCode":null,"errorMessage":"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","messagePattern":"Specified i18n\\.domains must be an array of domain objects e\\.g\\. \\[ (.+?) \\] received (.+?)\\.\nSee more info here: https://nextjs\\.org/docs/messages/invalid-i18n-config","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/next/src/server/config.ts","lineNumber":1228,"sourceCode":"      )\n    }\n\n    if (i18n.locales.length > 100 && !silent) {\n      Log.warn(\n        `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`\n      )\n    }\n\n    const defaultLocaleType = typeof i18n.defaultLocale\n\n    if (!i18n.defaultLocale || defaultLocaleType !== 'string') {\n      throw new Error(\n        `Specified i18n.defaultLocale should be a string.\\nSee more info here: https://nextjs.org/docs/messages/invalid-i18n-config`\n      )\n    }\n\n    if (typeof i18n.domains !== 'undefined' && !Array.isArray(i18n.domains)) {\n      throw new Error(\n        `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`\n      )\n    }\n\n    if (i18n.domains) {\n      const invalidDomainItems = i18n.domains.filter((item) => {\n        if (!item || typeof item !== 'object') return true\n        if (!item.defaultLocale) return true\n        if (!item.domain || typeof item.domain !== 'string') return true\n\n        if (item.domain.includes(':')) {\n          console.warn(\n            `i18n domain: \"${item.domain}\" is invalid it should be a valid domain without protocol (https://) or port (:3000) e.g. example.vercel.sh`\n          )\n          return true\n        }\n\n        const defaultLocaleDuplicate = i18n.domains?.find(","sourceCodeStart":1210,"sourceCodeEnd":1246,"githubUrl":"https://github.com/vercel/next.js/blob/0ae8c72462952df163f1b1e0726641bc5b40dc93/packages/next/src/server/config.ts#L1210-L1246","documentation":"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.","triggerScenarios":"Setting `i18n: { domains: { domain: 'example.fr', defaultLocale: 'fr' } }` (a single object instead of an array); `domains: 'example.fr'`; `domains: false`.","commonSituations":"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.","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."],"exampleFix":"// before\nmodule.exports = { i18n: { locales: ['fr','en'], defaultLocale: 'en', domains: { domain: 'example.fr', defaultLocale: 'fr' } } }\n// after\nmodule.exports = { i18n: { locales: ['fr','en'], defaultLocale: 'en', domains: [{ domain: 'example.fr', defaultLocale: 'fr', locales: ['fr'] }] } }","handlingStrategy":"validation","validationCode":"if (i18n.domains !== undefined && !Array.isArray(i18n.domains)) {\n  throw new Error('i18n.domains must be an array or undefined');\n}","typeGuard":"function hasValidDomains(i18n: any): boolean {\n  return i18n.domains === undefined || Array.isArray(i18n.domains);\n}","tryCatchPattern":null,"preventionTips":["Only add `domains` when using per-hostname locale routing; otherwise omit it.","Always wrap domain entries in an array literal."],"tags":["config","i18n","type-error"],"analyzedSha":"0ae8c72462952df163f1b1e0726641bc5b40dc93","analyzedAt":"2026-08-06T19:44:29.143Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}