- 
          
 - 
                Notifications
    
You must be signed in to change notification settings  - Fork 2.6k
 
Description
Describe the bug
If I have such a sidebar config object:
{
  "/a": [
    {
      "text": "a copy",
      "link": "/a/a-copy",
      "collapsed": true,
      "items": [
        {
          "text": "Runtime API Examples",
          "link": "/a/a-copy/api-examples.md",
          ".sort_base": "api-examples.md"
        },
        {
          "text": "Markdown Extension Examples",
          "link": "/a/a-copy/markdown-examples.md",
          ".sort_base": "markdown-examples.md"
        }
      ],
      ".sort_base": "a-copy"
    },
    {
      "text": "📂 b-copy",
      "collapsed": true,
      "items": [
        {
          "text": "Markdown Extension Examples",
          "link": "/a/b-copy/markdown-examples.md",
          ".sort_base": "markdown-examples.md"
        },
        {
          "text": "Runtime API Examples",
          "link": "/a/b-copy/z_api-examples.md",
          ".sort_base": "z_api-examples.md"
        }
      ],
      ".sort_base": "b-copy"
    }
  ],
  "/": [
    {
      "text": "Runtime API Examples",
      "link": "/api-examples.md",
      ".sort_base": "api-examples.md"
    },
    {
      "text": "Markdown Extension Examples",
      "link": "/markdown-examples.md",
      ".sort_base": "markdown-examples.md"
    },
    {
      "text": "a",
      "link": "/a",
      "collapsed": true,
      "items": [
        {
          "text": "a copy",
          "link": "/a/a-copy",
          "collapsed": true,
          "items": [
            {
              "text": "Runtime API Examples",
              "link": "/a/a-copy/api-examples.md",
              ".sort_base": "api-examples.md"
            },
            {
              "text": "Markdown Extension Examples",
              "link": "/a/a-copy/markdown-examples.md",
              ".sort_base": "markdown-examples.md"
            }
          ],
          ".sort_base": "a-copy"
        },
        {
          "text": "📂 b-copy",
          "collapsed": true,
          "items": [
            {
              "text": "Markdown Extension Examples",
              "link": "/a/b-copy/markdown-examples.md",
              ".sort_base": "markdown-examples.md"
            },
            {
              "text": "Runtime API Examples",
              "link": "/a/b-copy/z_api-examples.md",
              ".sort_base": "z_api-examples.md"
            }
          ],
          ".sort_base": "b-copy"
        }
      ],
      ".sort_base": "a"
    }
  ]
}when I access path "/api-examples.md", it will decide the sidebar to "/a", just because "/api-examples.md" starts with "/a".
Reproduction
Clone my repo, run
pnpm iand
pnpm run devgo to "http:///markdown-examples.html"
you will see the sidebar is good right now.
and click the Runtime API Examples, boomb💥 the sidebar which belongs to "/" disappeared.
Expected behavior
I expect that when i access path /api-examples.html, the sidebar remains same as when I access /markdown-examples.html.
System Info
$ npx envinfo --system --npmPackages vitepress --binaries --browsers
Need to install the following packages:
[email protected]
Ok to proceed? (y) y
  System:
    OS: Windows 11 10.0.26100
    CPU: (16) x64 AMD Ryzen 7 8845H w/ Radeon 780M Graphics
    Memory: 6.63 GB / 31.29 GB
  Binaries:
    Node: 23.7.0 - C:\nvm4w\nodejs\node.EXE
    Yarn: 1.22.22 - C:\nvm4w\nodejs\yarn.CMD
    npm: 10.9.2 - C:\nvm4w\nodejs\npm.CMD
    pnpm: 10.9.0 - C:\nvm4w\nodejs\pnpm.CMD
  Browsers:
    Edge: Chromium (138.0.3351.55)
  npmPackages:
    vitepress: ^1.6.3 => 1.6.3
Additional context
Tried to figure out the cause in vitepress sourcecode, and I think the function getSidebar in src\client\theme-default\support\sidebar.ts  is buggy, it shouldn't just only check the starting chararcters of the path, should also to check the remaining part after the same starting string...
/**
 * Get the `Sidebar` from sidebar option. This method will ensure to get correct
 * sidebar config from `MultiSideBarConfig` with various path combinations such
 * as matching `guide/` and `/guide/`. If no matching config was found, it will
 * return empty array.
 */
export function getSidebar(
  _sidebar: DefaultTheme.Sidebar | undefined,
  path: string
): SidebarItem[] {
  if (Array.isArray(_sidebar)) return addBase(_sidebar)
  if (_sidebar == null) return []
  path = ensureStartingSlash(path)
  const dir = Object.keys(_sidebar)
    .sort((a, b) => {
      return b.split('/').length - a.split('/').length
    })
    .find((dir) => {
      // make sure the multi sidebar key starts with slash too
      return path.startsWith(ensureStartingSlash(dir))
    })
  const sidebar = dir ? _sidebar[dir] : []
  return Array.isArray(sidebar)
    ? addBase(sidebar)
    : addBase(sidebar.items, sidebar.base)
}Thinking it will work this way:
/**
 * Get the `Sidebar` from sidebar option. This method will ensure to get correct
 * sidebar config from `MultiSideBarConfig` with various path combinations such
 * as matching `guide/` and `/guide/`. If no matching config was found, it will
 * return empty array.
 */
export function getSidebar(
  _sidebar: DefaultTheme.Sidebar | undefined,
  path: string
): SidebarItem[] {
  if (Array.isArray(_sidebar)) return addBase(_sidebar)
  if (_sidebar == null) return []
  path = ensureStartingSlash(path)
  const dir = Object.keys(_sidebar)
    .sort((a, b) => {
      // longer dir link has higher priority
      return b.split('/').length - a.split('/').length
    })
    .find((dir) => {
      const dirWithStartingSlash = ensureStartingSlash(dir)
      // make sure the multi sidebar key starts with slash too
      if (path.startsWith(dirWithStartingSlash)) {
        // "/" match everything and it has lowest priority
        if (dirWithStartingSlash === '/') return true
        const remains = path.replace(dirWithStartingSlash, '')
        if (remains.startsWith('/') || remains === '') return true
      }
    })
  const sidebar = dir ? _sidebar[dir] : []
  return Array.isArray(sidebar)
    ? addBase(sidebar)
    : addBase(sidebar.items, sidebar.base)
}Validations
- Check if you're on the latest VitePress version.
 - Follow our Code of Conduct
 - Read the docs.
 - Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.