Next.js中使用ni18n无法移除URL语言前缀问题求助
解决Next.js + ni18n自动跳转到/tr的问题
问题根源
你的代码存在两个核心问题导致自动跳转:
- React钩子使用违规:在
_app.tsx的条件判断块内调用useSyncLanguage,违反了钩子必须在组件顶层调用的规则,引发不可预测的路由行为。 - 语言同步逻辑强制覆盖URL:页面初始化时直接从localStorage取语言值并同步,完全忽略了URL本身的语言状态——如果localStorage里存过
tr,每次访问根路径都会被强制跳转到/tr。
修复步骤
1. 修正钩子使用错误,调整语言同步逻辑
修改_app.tsx,将客户端逻辑移到useEffect中,优先尊重URL的语言设置,仅在必要时同步localStorage的值:
import { useEffect } from 'react'; import type { AppPropsWithLayout } from 'next/app'; import { useRouter } from 'next/router'; import { useSyncLanguage } from 'ni18n'; function MyApp({ Component, pageProps }: AppPropsWithLayout) { const getLayout = Component.getLayout ?? ((page) => page); const { locale: currentUrlLocale } = useRouter(); // 钩子必须在组件顶层调用 useSyncLanguage(); useEffect(() => { const savedLocale = window.localStorage.getItem('locale'); // 初始化localStorage:如果没有保存的语言,设置默认值'en' if (!savedLocale) { window.localStorage.setItem('locale', 'en'); return; } // 仅当URL语言为空(根路径)且保存的语言不是默认值时,才同步 if (!currentUrlLocale && savedLocale !== 'en') { useSyncLanguage(savedLocale); } }, [currentUrlLocale]); return getLayout( <ThemeProvider attribute='class'> <Component {...pageProps} /> </ThemeProvider> ); } export default MyApp;
2. 对齐ni18n与Next.js的默认语言配置
在ni18n.config.ts中添加defaultLng,确保和Next.js的defaultLocale保持一致:
import type { Ni18nOptions } from 'ni18n' export const ni18nConfig: Ni18nOptions = { supportedLngs: ['en', 'tr'], ns: ['common','navbar'], defaultLng: 'en', // 新增:和Next.js默认语言对齐 }
3. 关闭Next.js自动语言检测(可选但推荐)
修改next.config.js,关闭浏览器语言自动检测,避免意外跳转:
module.exports = { i18n: { defaultLocale: 'en', locales: ['en', 'tr'], localeDetection: false, // 关闭自动检测浏览器语言 }, }
4. 清除浏览器缓存的旧语言值
在浏览器控制台执行以下命令,清除之前可能存下的tr值:
localStorage.removeItem('locale')
验证
完成以上修改后,访问http://localhost:3000,应该会停留在根路径,默认使用英文语言;手动切换语言后,localStorage会保存对应值,下次访问时会自动加载对应语言的路径。
内容的提问来源于stack exchange,提问作者delledev
相关产品推荐
相关产品推荐

