Next.js + next-i18next切换语言时页面自动重载问题求助
解决Next.js + next-i18next切换语言时页面重载并回到顶部的问题
我看了你的代码,核心问题出在语言切换的实现方式上——你现在用router.push来切换locale,这会触发Next.js加载对应locale的静态页面(因为你的首页用了getStaticProps,Next.js会为每个locale生成独立的静态文件),所以必然导致页面重载、回到顶部。
下面给你两种解决思路,按需选择:
方案一:直接在客户端切换语言(不修改URL)
这是最简单的方式,用next-i18next提供的i18n实例直接切换语言,完全避免路由跳转,组件只会重新渲染:
修改你的Options组件,引入useTranslation获取i18n对象,替换掉router.push:
import { useTranslation } from 'next-i18next'; // 别忘了导入 const Options = () => { const router = useRouter(); const { theme, resolvedTheme, setTheme } = useTheme(); const loaded = useLoaded(); const { i18n } = useTranslation(); // 获取i18n实例 return ( <StyledOptions> <ul> <li> <IconButton onClick={() => setTheme(resolvedTheme === 'light' ? 'dark':'light')} > {theme === 'dark' && loaded ? <MdLightMode /> : <MdDarkMode />} </IconButton> </li> <li onClick={() => i18n.changeLanguage('cs')}> {/* 替换为changeLanguage */} CZK </li> <li onClick={() => i18n.changeLanguage('en')}> {/* 替换为changeLanguage */} ENG </li> </ul> </StyledOptions> ); }; export default Options;
这种方式的优势是:
- 完全无页面重载,组件只重新渲染翻译内容
- 保持当前滚动位置不变
- 代码改动极小
方案二:切换语言同时更新URL(保持locale在地址栏可见)
如果需要地址栏显示对应locale(比如/cs或/en),可以结合i18n.changeLanguage和router.replace,并加上shallow: true参数(避免触发页面重载和重新执行getStaticProps):
修改Options组件的点击事件:
import { useTranslation } from 'next-i18next'; const Options = () => { const router = useRouter(); const { theme, resolvedTheme, setTheme } = useTheme(); const loaded = useLoaded(); const { i18n } = useTranslation(); // 封装语言切换逻辑 const switchLanguage = async (lang: string) => { await i18n.changeLanguage(lang); // 用replace更新路由,shallow: true确保只在客户端更新,不触发页面重载 router.replace(router.pathname, router.asPath, { locale: lang, shallow: true }); }; return ( <StyledOptions> <ul> <li> <IconButton onClick={() => setTheme(resolvedTheme === 'light' ? 'dark':'light')} > {theme === 'dark' && loaded ? <MdLightMode /> : <MdDarkMode />} </IconButton> </li> <li onClick={() => switchLanguage('cs')}> CZK </li> <li onClick={() => switchLanguage('en')}> ENG </li> </ul> </StyledOptions> ); }; export default Options;
注意:shallow: true只适用于同一页面内的路由变化,你的场景是首页切换语言,完全符合这个条件。
额外检查点
确保你的_app.tsx已经正确用appWithTranslation高阶组件包裹,这是next-i18next正常工作的前提:
import { appWithTranslation } from 'next-i18next'; function MyApp({ Component, pageProps }) { return <Component {...pageProps} />; } export default appWithTranslation(MyApp);
你的getStaticProps配置是正确的,serverSideTranslations已经正确注入了翻译资源,不需要改动。
内容的提问来源于stack exchange,提问作者KarlZ
相关产品推荐
相关产品推荐

