Docusaurus 的 SSR 模式下怎么处理动态路由参数?

萌新.窅恒 阅读 10

我在用 Docusaurus 做一个文档站点,想通过 URL 动态传参来加载不同内容,比如 /tool/:id 这种形式。但发现 Docusaurus 默认是静态生成的,根本拿不到运行时的路由参数,页面一刷新就 404 了。

我试过在 routes.js 里加自定义路由,也查了官方文档关于客户端路由的部分,但 SSR 阶段还是报错。有没有办法在保持 SSG/SSR 的同时,支持这种带参数的动态页面?

现在我的配置大概是这样:

module.exports = {
  presets: [
    [
      '@docusaurus/preset-classic',
      {
        pages: {
          routeBasePath: '/',
        },
      },
    ],
  ],
};
我来解答 赞 1 收藏
二维码
手机扫码查看
1 条解答
秀兰 Dev
这个问题我之前也踩过坑。Docusaurus 本质上是个静态站点生成器,它的设计理念就是在构建时把所有页面都生成好,所以像 /tool/:id 这种运行时动态路由,刷新 404 是必然的——服务器上压根就没有这个物理文件嘛。

要解决这个问题,核心思路是利用 Docusaurus 的插件系统注入自定义路由,然后配合 SPA fallback 机制。具体来说分三步走。

第一步,写一个自定义插件来注册动态路由。在你的项目根目录创建 plugins/dynamicRoutePlugin.js

module.exports = function (context, options) {
return {
name: 'dynamic-route-plugin',

// 在路由扩展阶段注入我们的动态路由
extendRoutes({ addRoute }) {
// 添加 /tool/:id 路由,指向自定义组件
addRoute({
path: '/tool/:id',
component: '@site/src/pages/tool/[id].js',
// 重要:这个路由要精确匹配
exact: true,
// 设置优先级,确保能覆盖默认行为
priority: 'high',
});

return {
// 告诉 Docusaurus 这个路由需要客户端处理
// 这样刷新时不会直接报 404
};
},
};
};


第二步,创建对应的页面组件 src/pages/tool/[id].js。注意 Docusaurus 不像 Next.js 那样原生支持文件名动态参数,我们得手动处理:

import React from 'react';
import Layout from '@theme/Layout';
import { useLocation } from '@docusaurus/router';

export default function ToolPage() {
const location = useLocation();

// 从 URL 中提取 id 参数
// 因为 Docusaurus 的路由限制,我们需要手动解析
const pathParts = location.pathname.split('/');
const toolId = pathParts[2]; // ['', 'tool', 'id'] 取第三段

// 根据 id 加载不同内容,这里可以接入你的数据源
const getToolContent = (id) => {
// 实际项目中这里可能是 API 调用或者本地数据查询
const tools = {
'converter': { title: '格式转换器', desc: '支持多种格式互转' },
'analyzer': { title: '代码分析器', desc: '静态代码分析工具' },
};
return tools[id] || { title: '未知工具', desc: '该工具不存在' };
};

const tool = getToolContent(toolId);

return (


{tool.title}


工具 ID: {toolId}


{tool.desc}




);
}


第三步,也是最关键的一步,解决刷新 404 的问题。这需要在 docusaurus.config.js 里注册插件,并且配置托管平台的重定向规则:

module.exports = {
presets: [
[
'@docusaurus/preset-classic',
{
pages: {
routeBasePath: '/',
},
},
],
],

// 注册我们的自定义插件
plugins: [
'./plugins/dynamicRoutePlugin',
],

// 重要:配置 trailingSlash 可以影响路由匹配行为
trailingSlash: false,
};


但是!光这样还不够,刷新 404 的根本原因是静态托管服务器找不到对应文件。你需要根据部署平台配置 URL 重写规则。

如果是 Nginx,配置类似这样:

location ~ ^/tool/ {
# 所有 /tool/* 请求都返回 index.html,让前端路由处理
try_files $uri $uri/ /index.html;
}


如果是 Netlify,在 static/_redirects 文件里加一行:

/tool/* /index.html 200


如果是 Vercel,在 vercel.json 里配置:

{
"rewrites": [
{ "source": "/tool/:id*", "destination": "/index.html" }
]
}


原理其实很简单:服务器收到 /tool/abc 请求时,不管 abc 是什么都返回主入口 index.html,然后 Docusaurus 的前端路由接管,从 URL 里解析参数渲染对应内容。这就是典型的 SPA fallback 策略。

还有个备选方案,如果你的工具 ID 是有限的、可枚举的,可以在构建时就把所有页面生成出来。写个脚本在构建前生成对应的 .js 文件,这样就是真正的静态页面,不存在刷新问题。但如果 ID 是动态无限的,还是得用上面这套方案。

说实话 Docusaurus 在这块确实不如 Next.js 方便,毕竟它定位是文档站而非通用框架。不过用插件系统扩展一下也还能凑合用。
点赞 1
2026-03-01 20:04