Next.js项目部署在子目录时如何生成locale位于basePath之后的跳转链接
问题核心原因
Next.js 内置的 i18n 路由逻辑默认会将 locale 标识拼接在 basePath 之前,这是路径顺序错误的核心诱因。以下是可直接落地的修复方案:
第一步:调整 next.config.js 配置
// next.config.js const { i18n } = require('./next-i18next.config'); module.exports = { i18n: { ...i18n, // 关闭Next.js自动给路径加locale前缀的默认逻辑,改为手动控制 localePrefix: 'never', }, // 全环境统一配置basePath,生产环境同样部署在/app子目录下,无需差异化配置 basePath: '/app', assetPrefix: '/app/', async rewrites() { return [ // 外部访问路径/app/<locale>/*映射到Next.js内部页面路由 { source: '/:locale/:path*', destination: '/:path*', }, ]; }, async redirects() { return [ // 访问根路径/app时自动跳转到默认语言路径,可替换为你自己的默认locale { source: '/', destination: `/zh-CN`, permanent: false, basePath: true, }, ]; }, };
第二步:修改自定义Link组件逻辑
// link.tsx import React from 'react'; import NextLink, { LinkProps } from 'next/link'; import { useRouter } from 'next/router'; export interface ILinkProps extends LinkProps { children: React.ReactChild; asLink?: boolean; } Link.defaultProps = { asLink: false, }; export default function Link(props: ILinkProps): React.ReactElement { const { children, asLink, href, locale, ...rest } = props; const router = useRouter(); // 可替换为你自己的默认locale const currentLocale = locale || router.locale || 'zh-CN'; // 手动拼接路径:/locale/实际页面路径,basePath会由Next.js自动加在最前面 const processedHref = typeof href === 'string' ? `/${currentLocale}${href.startsWith('/') ? href : `/${href}`}` : { ...href, pathname: `/${currentLocale}${href.pathname?.startsWith('/') ? href.pathname : `/${href.pathname}`}` }; return ( <> {asLink ? ( <NextLink {...rest} href={processedHref} // 关闭Next.js自动加locale前缀的逻辑,避免重复拼接 locale={false} passHref > {children} </NextLink> ) : ( children )} </> ); }
第三步:适配编程式跳转
如果项目中使用 useRouter 的 push/replace 方法做跳转,需要和Link组件保持相同的处理逻辑:
const router = useRouter() // 跳转示例 router.push(`/${router.locale}/dashboard`, undefined, { locale: false })
配置完成后,跳转路径将完全符合 example.com/app/<locale>/<pageName> 的预期格式,也不会出现重复 /app 的路径异常问题。
内容的提问来源于stack exchange,提问作者Dawid Mazewski
相关产品推荐
相关产品推荐

