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

NextJS带版本前缀的可选路由段实现方案咨询

在NextJS中实现多版本文档路由方案

针对你需要的多版本文档路由(/foo/bar对应最新版本,/x.y.z/foo/bar对应指定旧版本),同时共享渲染逻辑的需求,以下是两种适配不同NextJS路由体系的实现方案:


方案一:NextJS 13+ App Router

利用路由组、动态段正则约束和重写规则实现,既能避免误匹配,又能统一渲染逻辑。

1. 目录结构

创建带路由组的动态路由结构,路由组(docs)不会影响最终URL路径:

app/
└── (docs)/
    └── [version]/
        └── [...slug]/
            └── page.tsx
components/
└── DocsPage.tsx  # 统一渲染组件

2. 配置路由重写与匹配规则

在next.config.js中添加重写规则,将不带版本的路径指向latest版本,同时限制[version]仅匹配版本号格式(如x.y.z):

/** @type {import('next').NextConfig} */
const nextConfig = {
  async rewrites() {
    return [
      // 重写无版本路径到latest版本
      {
        source: '/:slug*',
        destination: '/latest/:slug*',
        // 排除已带合法版本号的路径
        missing: [
          {
            type: 'pathname',
            value: '/:version(\\d+\\.\\d+\\.\\d+)/:slug*',
          },
        ],
      },
    ];
  },
};

module.exports = nextConfig;

如果需要支持更宽松的版本格式(如x.y、x或预发布版x.y.z-beta),可将正则调整为^\\d+(\\.\\d+){0,2}(-[a-zA-Z0-9]+)?$

3. 统一渲染逻辑实现

在app/(docs)/[version]/[...slug]/page.tsx中处理版本参数,调用统一的渲染组件:

import DocsPage from '@/components/DocsPage';
import { getDocData } from '@/lib/docs';

type Props = {
  params: {
    version: string;
    slug: string[];
  };
};

export default async function Page({ params }: Props) {
  const { version, slug } = params;
  // 将latest映射为实际的最新版本号(可从配置或接口获取)
  const actualVersion = version === 'latest' ? '2.0.0' : version;
  // 根据版本和slug获取对应文档数据
  const docData = await getDocData(actualVersion, slug.join('/'));

  return <DocsPage data={docData} version={actualVersion} />;
}

// 静态生成场景:预生成所有版本+文档路径的组合
export async function generateStaticParams() {
  const versions = ['1.0.0', '2.0.0', 'latest'];
  // 实际可从文档源(如Markdown文件目录)自动获取所有slug
  const slugs = ['foo/bar', 'foo/baz', 'guide/quick-start'];

  return versions.flatMap(version => 
    slugs.map(slug => ({
      version,
      slug: slug.split('/'),
    }))
  );
}

4. 统一渲染组件

将文档渲染逻辑抽离到components/DocsPage.tsx,实现逻辑复用:

type DocsPageProps = {
  data: { title: string; content: string }; // 根据实际文档数据定义类型
  version: string;
};

export default function DocsPage({ data, version }: DocsPageProps) {
  return (
    <div className="docs-container">
      <div className="version-tag">当前版本:{version}</div>
      <h1>{data.title}</h1>
      <div className="doc-content">{data.content}</div>
    </div>
  );
}

方案二:NextJS Pages Router

通过自定义重写规则和动态路由页面实现,适配NextJS 12及更早版本。

1. 目录结构

创建动态路由页面,所有文档请求都通过该页面处理:

pages/
└── [version]/
    └── [...slug].js
components/
└── DocsPage.js  # 统一渲染组件

2. 配置路由重写

在next.config.js中添加重写规则,逻辑同App Router:

module.exports = {
  async rewrites() {
    return [
      {
        source: '/:slug*',
        destination: '/latest/:slug*',
        missing: [
          {
            type: 'pathname',
            value: '/:version(\\d+\\.\\d+\\.\\d+)/:slug*',
          },
        ],
      },
    ];
  },
};

3. 动态路由页面处理

在pages/[version]/[...slug].js中获取版本和slug,传递给统一组件:

import DocsPage from '../../components/DocsPage';
import { getDocData } from '../../lib/docs';

export async function getServerSideProps(context) {
  const { version, slug } = context.params;
  const actualVersion = version === 'latest' ? '2.0.0' : version;
  const docData = await getDocData(actualVersion, slug.join('/'));

  return {
    props: {
      data: docData,
      version: actualVersion,
    },
  };
}

// 静态生成场景替换为getStaticPaths和getStaticProps
// export async function getStaticPaths() { /* 生成所有路径 */ }
// export async function getStaticProps(context) { /* 获取数据 */ }

export default DocsPage;

4. 统一渲染组件

同App Router方案,将渲染逻辑抽离到components/DocsPage.js即可。


关键注意事项

  • 版本号匹配规则:根据实际版本格式调整正则,避免误匹配非版本路径。
  • 静态生成优化:如果采用SSG,需确保所有版本和文档路径的组合都被预生成,可通过脚本自动扫描文档目录生成generateStaticParams或getStaticPaths的返回值。
  • 版本切换:可在页面顶部添加版本选择器,通过链接到/${version}/foo/bar实现版本切换。

内容的提问来源于stack exchange,提问作者Sean Mackesey

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 21:55:16