next-i18next支持动态修改默认语言吗?基于顶级域名配置
当然可以根据顶级域名动态设置next-i18next的默认语言,结合localeSubpaths也完全没问题!我给你梳理下具体的实现思路和代码示例,顺便帮你修正下示例里的小语法错误~
实现步骤
1. 编写工具函数解析顶级域名
首先我们需要一个通用函数,从域名里提取顶级域名(TLD),然后映射到对应的语言:
// utils/getDefaultLanguage.js export const getDefaultLanguageFromTLD = (host) => { // 从host里拆分出顶级域名,比如"example.de" → "de" const tld = host.split('.').pop(); // 可以根据你的需求扩展更多TLD和语言的映射关系 switch(tld) { case 'de': return 'de'; case 'it': return 'it'; default: return 'en'; // 兜底的默认语言 } };
2. 动态设置默认语言(服务端+客户端)
因为Next.js是同构渲染,我们需要同时处理服务端和客户端的场景:
服务端处理(getInitialProps)
在_app.js里,通过getInitialProps获取请求的域名,动态修改i18n的默认语言:
// pages/_app.js import { appWithTranslation } from 'next-i18next'; import { getDefaultLanguageFromTLD } from '../utils/getDefaultLanguage'; function MyApp({ Component, pageProps }) { return <Component {...pageProps} />; } MyApp.getInitialProps = async ({ ctx }) => { // 服务端从req.headers.host拿域名,客户端从window.location.host拿 const host = ctx.req ? ctx.req.headers.host : window.location.host; const defaultLanguage = getDefaultLanguageFromTLD(host); // 获取i18n实例,动态修改默认语言 const i18n = ctx.i18n; if (i18n) { i18n.defaultLng = defaultLanguage; // 如果用户没有手动切换过语言(没有对应的cookie),就自动切换到TLD对应的语言 if (!ctx.req?.cookies?.['i18next']) { await i18n.changeLanguage(defaultLanguage); } } return {}; }; export default appWithTranslation(MyApp);
客户端处理(useEffect)
如果用户是客户端路由跳转(比如页面内导航),我们需要在客户端初始化时也做一次判断:
// 继续在pages/_app.js里添加 import { useEffect } from 'react'; import { useTranslation } from 'next-i18next'; function MyApp({ Component, pageProps }) { const { i18n } = useTranslation(); useEffect(() => { // 检查用户是否有保存的语言偏好,没有的话根据TLD设置 if (!localStorage.getItem('i18nextLng')) { const host = window.location.host; const defaultLanguage = getDefaultLanguageFromTLD(host); i18n.changeLanguage(defaultLanguage); } }, [i18n]); return <Component {...pageProps} />; }
3. 配置localeSubpaths
确保你的next.config.js里的国际化配置正确,localeSubpaths要和你的语言列表对应:
// next.config.js module.exports = { i18n: { locales: ['en', 'de', 'it'], defaultLocale: 'en', // 这里留一个兜底值,实际会被动态覆盖 localeSubpaths: { de: 'de', it: 'it', en: 'en', }, }, };
小提示:修正你的示例代码
你写的三元表达式顺序反啦,正确的写法应该是:
const defaultLanguage = topLevelDomain === "de" ? "de" : "it";
这样就可以实现“访问.de域名默认用德语,.it域名默认用意大利语”的需求,同时localeSubpaths也能正常工作,不会冲突~
内容的提问来源于stack exchange,提问作者Piotr O
相关产品推荐
相关产品推荐

