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

Docusaurus:Swizzle Navbar实现不同版本导航项显示控制

Docusaurus 按版本动态切换Navbar导航项实现方案

可行性说明

完全不需要Eject,用Swizzle的Wrapping模式就能实现。这种方式不会修改官方原始组件代码,既能保留自定义逻辑,还能兼容后续官方的组件更新,比Eject靠谱得多。

实现流程(基于已Swizzle的Navbar/NavbarItem组件)

  1. 获取当前文档版本
    在你Swizzle后的Navbar组件文件(一般是src/theme/Navbar.js)中,引入Docusaurus的版本上下文钩子,用来获取当前浏览的文档版本:

    import { useVersionContext } from '@docusaurus/plugin-content-docs/client';
    

    然后在组件内部解构获取版本号:

    const { version } = useVersionContext();
    
  2. 编写版本对比逻辑
    写一个简单的工具函数,用来判断当前版本是否大于等于目标版本(这里是1.3.0):

    const isVersionGreaterOrEqual = (currentVersion, targetVersion) => {
      const currentParts = currentVersion.split('.').map(Number);
      const targetParts = targetVersion.split('.').map(Number);
      for (let i = 0; i < Math.max(currentParts.length, targetParts.length); i++) {
        const curr = currentParts[i] || 0;
        const target = targetParts[i] || 0;
        if (curr > target) return true;
        if (curr < target) return false;
      }
      return true; // 版本完全相同时返回true
    };
    

    接着用这个函数判断是否要显示新版导航:

    const showNewNavbar = isVersionGreaterOrEqual(version, '1.3.0');
    
  3. 动态渲染导航项
    在Navbar的Wrapper组件中,根据showNewNavbar的值,分别定义不同版本对应的导航项,再注入到原始Navbar的props中:

    import Navbar from '@theme-original/Navbar';
    import { useVersionContext } from '@docusaurus/plugin-content-docs/client';
    import NavbarDropdown from '@theme/NavbarDropdown';
    import NavbarItem from '@theme/NavbarItem';
    
    export default function NavbarWrapper(props) {
      const { version } = useVersionContext();
    
      const isVersionGreaterOrEqual = (currentVersion, targetVersion) => {
        const currentParts = currentVersion.split('.').map(Number);
        const targetParts = targetVersion.split('.').map(Number);
        for (let i = 0; i < Math.max(currentParts.length, targetParts.length); i++) {
          const curr = currentParts[i] || 0;
          const target = targetParts[i] || 0;
          if (curr > target) return true;
          if (curr < target) return false;
        }
        return true;
      };
    
      const showNewNavbar = isVersionGreaterOrEqual(version, '1.3.0');
    
      // 定义不同版本对应的导航项
      const customNavItems = showNewNavbar ? [
        <NavbarDropdown label="Dropdown B" key="dropdown-b">
          <NavbarItem to="/docs/v1.3.0/guide">新指南</NavbarItem>
          <NavbarItem to="/docs/v1.3.0/api">新API</NavbarItem>
        </NavbarDropdown>,
        <NavbarItem to="/docs/v1.3.0/changelog" key="changelog">更新日志</NavbarItem>
      ] : [
        <NavbarDropdown label="Dropdown A" key="dropdown-a">
          <NavbarItem to="/docs/v1.2.0/basic">基础使用</NavbarItem>
          <NavbarItem to="/docs/v1.2.0/troubleshoot">问题排查</NavbarItem>
        </NavbarDropdown>
      ];
    
      // 合并自定义导航项与原始导航项,渲染Navbar
      return <Navbar {...props} items={[...customNavItems, ...props.items]} />;
    }
    
    • 如果你的项目原本有默认导航项,...props.items会保留这些项,你可以调整自定义项和原始项的顺序(比如把自定义项放在后面就改成[...props.items, ...customNavItems])。
  4. 测试验证
    切换不同版本的文档,检查Navbar显示:1.2.0及以下版本仅显示Dropdown A,1.3.0及以上版本显示Dropdown B和额外的导航项。

注意事项

  • Swizzle时一定要选Wrap模式,不要选Eject。Wrap模式是在官方组件外层包裹自定义逻辑,后续官方更新Navbar组件时,你的代码不会被覆盖;而Eject会把官方组件代码完全复制到本地,后续无法接收官方更新,维护成本极高。
  • 如果之前不小心Swizzle成了Eject模式,建议重新执行Swizzle命令,选择Wrap模式覆盖。

内容的提问来源于stack exchange,提问作者Aneesha S

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 04:16:06