Next.js多域名i18n配置疑问:多域名能否设置同一默认Locale?
多域名共享同一默认Locale的Next.js配置问题
我计划将Next.js站点部署在Vercel上,希望为不同域名配置不同的默认语言。以下是精简后的next.config.js配置代码:
module.exports = { i18n: { locales: ['en', 'cs'], defaultLocale: 'en', localeDetection: true, domains: [{ domain: 'humanely.it', defaultLocale: 'en', }, { domain: 'lidsky.it', defaultLocale: 'cs', }, { domain: 'itlidsky.cz', defaultLocale: 'cs', }], }, }
运行后出现如下错误:
Both lidsky.it and itlidsky.cz configured the defaultLocale cs but only one can. Change one item's default locale to continue Both itlidsky.cz and lidsky.it configured the defaultLocale cs but only one can. Change one item's default locale to continue Error: Invalid i18n.domains values: {"domain":"lidsky.it","defaultLocale":"cs"} {"domain":"itlidsky.cz","defaultLocale":"cs"}
我理解错误提示,但疑惑:Next.js真的不允许两个不同域名设置同一默认Locale吗?多个域名使用同一默认Locale是合理的,请问是否有办法实现该配置,或者这是Next.js的设计缺陷?
解决方案
Next.js的i18n域名配置确实存在这个限制——不允许多个域名映射到同一个默认Locale,这是框架的设计约束,并非缺陷。要实现多域名共享同一默认Locale的需求,可以采用以下两种方案:
方案1:Vercel重写规则 + Next.js中间件
- 从
next.config.js的domains数组中移除其中一个共享Locale的域名(比如itlidsky.cz) - 编写Next.js中间件(
middleware.js),检测请求域名,自动为对应域名设置目标Locale:
import { NextResponse } from 'next/server'; export function middleware(request) { const { hostname, nextUrl } = request; let targetLocale = nextUrl.locale || 'en'; // 匹配需要设置cs为默认Locale的域名 if (hostname === 'lidsky.it' || hostname === 'itlidsky.cz') { targetLocale = 'cs'; } // 若当前Locale与目标不一致,重定向到对应Locale路径 if (nextUrl.locale !== targetLocale) { return NextResponse.redirect( new URL(`/${targetLocale}${nextUrl.pathname}${nextUrl.search}`, request.url) ); } return NextResponse.next(); } // 排除不需要处理的静态资源和API路径 export const config = { matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'], };
- 在Vercel项目设置中,将
itlidsky.cz添加为自定义域名,确保域名解析正确指向Vercel服务器。
方案2:客户端Locale手动检测(仅适用于CSR场景)
关闭next.config.js中的localeDetection: false,然后在根布局或页面组件中,根据当前域名手动切换Locale:
'use client'; import { useRouter } from 'next/router'; import { useEffect } from 'react'; export default function RootLayout({ children }) { const router = useRouter(); useEffect(() => { const hostname = window.location.hostname; const desiredLocale = (hostname === 'lidsky.it' || hostname === 'itlidsky.cz') ? 'cs' : 'en'; if (router.locale !== desiredLocale) { router.push('/', undefined, { locale: desiredLocale }); } }, [router]); return <>{children}</>; }
注意:该方案仅在客户端渲染时生效,服务端渲染场景建议优先使用方案1。
内容的提问来源于stack exchange,提问作者Patrik Šimunič
相关产品推荐
相关产品推荐

