Next.js App目录中router.push传参切换语言失效问题
Next.js App Router 多语言切换路由跳转失效问题解决
你遇到的问题核心是:App Router 中 usePathname() 返回的是实际访问路径(比如 /en/product/3),而非动态路由的模板(/[lang]/product/[id])。当你把实际路径传给 router.push() 并附带 params 时,Next.js 找不到可替换的动态占位符,所以跳转逻辑不生效。
解决方案:手动替换路径中的语言参数
最灵活的方式是通过正则表达式替换路径开头的语言段,无需硬编码路由结构:
修改 handleChange 函数如下:
const handleChange = (key: string) => { if (key !== params.lang) { // 替换路径开头的语言参数 const newPath = pathname.replace(/^\/[^/]+/, `/${key}`); router.push(newPath); } }
另一种硬编码路由模板的方式(适合固定路由结构)
如果你的路由结构固定为 /[lang]/product/[id],也可以直接传入动态路由模板和参数:
const handleChange = (key: string) => { if (key !== params.lang) { router.push('/[lang]/product/[id]', { params: { lang: key, id: params.id } }); } }
修改后的完整组件代码
'use client' import { useParams, usePathname, useRouter } from 'next/navigation' import { language } from '~/helper/data/common' function SwitchLang() { const router = useRouter() const params = useParams() as { lang: string; id: string } const pathname = usePathname() const localeData = language.find((item) => item.key === params.lang) const handleChange = (key: string) => { if (key !== params.lang) { const newPath = pathname.replace(/^\/[^/]+/, `/${key}`); router.push(newPath); } } return ( <div className="relative border border-common-black px-2 py-1 rounded select-none cursor-pointer" > <div className="w-6 text-center">{localeData?.label}</div> <div className="absolute left-0 top-[calc(100%+2px)] w-full shadow-lg bg-common-white rounded "> {language.map((item) => ( <div key={item.key} // 建议用item.key作为key,比index更稳定 className="px-2 py-1 hover:bg-[#ddd] text-center" onClick={() => handleChange(item.key)} > {item.label} </div> ))} </div> </div> ) } export default SwitchLang
补充小优化:循环渲染时建议用item.key作为key,比index更稳定,避免组件不必要的重渲染。
内容的提问来源于stack exchange,提问作者kan
相关产品推荐
相关产品推荐

