diff --git a/src/client/theme-default/components/SideBar.ts b/src/client/theme-default/components/SideBar.ts index 8a8b677c..89988165 100644 --- a/src/client/theme-default/components/SideBar.ts +++ b/src/client/theme-default/components/SideBar.ts @@ -6,7 +6,7 @@ import { } from 'vitepress' import { computed, h, FunctionalComponent, VNode } from 'vue' import { Header } from '../../../../types/shared' -import { isActive, getPathDirName } from '../utils' +import { isActive, joinUrl, getPathDirName } from '../utils' import { DefaultTheme } from '../config' import { useActiveSidebarLinks } from '../composables/activeSidebarLink' @@ -21,7 +21,7 @@ const SideBarItem: FunctionalComponent<{ const pageData = usePageData() const siteData = useSiteData() - const link = `${siteData.value.base}${relLink || ''}` + const link = resolveLink(siteData.value.base, relLink || '') const active = isActive(route, link) const headers = pageData.value.headers @@ -150,6 +150,10 @@ function resolveMultiSidebar( return [] } +function resolveLink(base: string, path: string): string | undefined { + return path ? joinUrl(base, path || '') : undefined +} + function createLink(active: boolean, text: string, link?: string): VNode { const tag = link ? 'a' : 'p' diff --git a/src/client/theme-default/utils.ts b/src/client/theme-default/utils.ts index 25d6580a..b2ff533e 100644 --- a/src/client/theme-default/utils.ts +++ b/src/client/theme-default/utils.ts @@ -27,6 +27,21 @@ export function normalize(path: string): string { return decodeURI(path).replace(hashRE, '').replace(extRE, '') } +export function joinUrl(base: string, path: string): string { + const baseEndsWithSlash = base.endsWith('/') + const pathStartsWithSlash = path.startsWith('/') + + if (baseEndsWithSlash && pathStartsWithSlash) { + return base.slice(0, -1) + path + } + + if (!baseEndsWithSlash && !pathStartsWithSlash) { + return `${base}/${path}` + } + + return base + path +} + /** * get the path without filename (the last segment). for example, if the given * path is `/guide/getting-started.html`, this method will return `/guide/`.