You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 01:36:03