Docusaurus 的 SSR 模式下怎么处理动态路由参数?
我在用 Docusaurus 做一个文档站点,想通过 URL 动态传参来加载不同内容,比如 /tool/:id 这种形式。但发现 Docusaurus 默认是静态生成的,根本拿不到运行时的路由参数,页面一刷新就 404 了。
我试过在 routes.js 里加自定义路由,也查了官方文档关于客户端路由的部分,但 SSR 阶段还是报错。有没有办法在保持 SSG/SSR 的同时,支持这种带参数的动态页面?
现在我的配置大概是这样:
module.exports = {
presets: [
[
'@docusaurus/preset-classic',
{
pages: {
routeBasePath: '/',
},
},
],
],
};
要解决这个问题,核心思路是利用 Docusaurus 的插件系统注入自定义路由,然后配合 SPA fallback 机制。具体来说分三步走。
第一步,写一个自定义插件来注册动态路由。在你的项目根目录创建
plugins/dynamicRoutePlugin.js:第二步,创建对应的页面组件
src/pages/tool/[id].js。注意 Docusaurus 不像 Next.js 那样原生支持文件名动态参数,我们得手动处理:第三步,也是最关键的一步,解决刷新 404 的问题。这需要在
docusaurus.config.js里注册插件,并且配置托管平台的重定向规则:但是!光这样还不够,刷新 404 的根本原因是静态托管服务器找不到对应文件。你需要根据部署平台配置 URL 重写规则。
如果是 Nginx,配置类似这样:
如果是 Netlify,在
static/_redirects文件里加一行:如果是 Vercel,在
vercel.json里配置:原理其实很简单:服务器收到 /tool/abc 请求时,不管 abc 是什么都返回主入口 index.html,然后 Docusaurus 的前端路由接管,从 URL 里解析参数渲染对应内容。这就是典型的 SPA fallback 策略。
还有个备选方案,如果你的工具 ID 是有限的、可枚举的,可以在构建时就把所有页面生成出来。写个脚本在构建前生成对应的 .js 文件,这样就是真正的静态页面,不存在刷新问题。但如果 ID 是动态无限的,还是得用上面这套方案。
说实话 Docusaurus 在这块确实不如 Next.js 方便,毕竟它定位是文档站而非通用框架。不过用插件系统扩展一下也还能凑合用。