首页 > 解决方案 > 如何将 Docusaurus 中的动态路由与 react-router 集成

问题描述

我有一个使用 Docusaurus v2 制作的网站,目前包含文档。但是,我想添加工作流列表的页面,如果单击列表中的工作流,用户将看到该工作流的其他详细信息页面。现在它似乎docusaurus.config 正在处理大部分路由,但是有没有办法可以添加动态路由,比如/workflows/:id?我制作了一个单独的独立应用程序,它有一个 Router 对象,如果我的 App.js 看起来像这样,它就可以工作:

// App.js
import Navigation from './Navigation'
import {BrowserRouter as Router, Switch, Route} from 'react-router-dom';

function App() {
  return (
  <Router>
    <Navigation />
    <Switch>
      <Route path="/" exact component={Home}></Route>
      <Route path="/workflows" exact component={Workflows}></Route>
      <Route path="/workflows/:id" component={WorkflowItem}></Route>
    </Switch>
  </Router>
  )
}

是否可以在 Docusaurus 的某处添加路由器?谢谢!

标签: javascriptreactjsdocusaurus

解决方案


我通过创建一个简单的插件来添加我自己的自定义路由来解决这个问题。文档在这里

让我们调用插件plugin-dynamic-routes

// {SITE_ROOT_DIR}/plugin-dynamic-routes/index.js

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

        async contentLoaded({ content, actions }) {
            const { routes } = options
            const { addRoute } = actions

            routes.map(route => addRoute(route))
        }
    }
}
// docusaurus.config.js
const path = require('path')

module.exports = {
    // ...
    plugins: [
        [
            path.resolve(__dirname, 'plugin-dynamic-routes'),
            { // this is the options object passed to the plugin
                routes: [
                    { // using Route schema from react-router
                        path: '/workflows',
                        exact: false, // this is needed for sub-routes to match!
                        component: '@site/path/to/component/App'
                    }
                ]
            }
        ],
    ],
}

您也许可以使用上述方法来配置子路由,但我还没有尝试过。对于自定义页面,您只需要Switch组件(此时从技术上讲,您正在使用嵌套路由)。该Layout组件用于将页面集成到 Docusaurus 站点的其余部分。

// App.js

import React from 'react'
import Layout from '@theme/Layout'
import { Switch, Route, useRouteMatch } from '@docusaurus/router'

function App() {
    let match = useRouteMatch()

    return (
        <Layout title="Page Title">
            <Switch>
                <Route path={`${match.path}/:id`} component={WorkflowItem} />
                <Route path={match.path} component={Workflows} />
            </Switch>
        </Layout>
    )
}

推荐阅读