vitepress-plugin-breadcrumbs
VitePress-style dynamic breadcrumbs built from the current page's position in the sidebar. Makes no assumption about content structure, so it fits any VitePress project.
Installation
npm install @ampernic/vitepress-plugin-breadcrumbsConcept
The full breadcrumb trail is composed as:
prefix -> home -> ancestor groups from the sidebar -> current page- Every trail entry carries a link.
- The last crumb whose link matches the current route becomes the current one (so a document index/landing shows its own crumb as current); otherwise the current page is appended as a separate entry.
- Consecutive crumbs with the same link collapse (dedup).
hideSinglethen hides a lone crumb (for example, on a bare landing).
The sidebar path is looked up in themeConfig.sidebar (array, SidebarMulti and { base, items } groups are all supported). When the page is not found in the sidebar and fallback: 'path' is set, breadcrumbs are derived from URL segments.
Usage
Add the component to a layout slot (usually doc-before, above the page title):
// .vitepress/theme/index.ts
import DefaultTheme from 'vitepress/theme'
import { h } from 'vue'
import Breadcrumbs from '@ampernic/vitepress-plugin-breadcrumbs/components/Breadcrumbs.vue'
export default {
extends: DefaultTheme,
Layout: () =>
h(DefaultTheme.Layout, null, {
'doc-before': () => h(Breadcrumbs),
}),
}Configuration
Globally via themeConfig.breadcrumbs or per-prop (props beat config, config beats defaults). The config can be typed with defineBreadcrumbsConfig:
// .vitepress/config.ts
import { defineBreadcrumbsConfig } from '@ampernic/vitepress-plugin-breadcrumbs'
export default {
themeConfig: {
breadcrumbs: defineBreadcrumbsConfig({
home: 'auto',
separator: '>',
hideSingle: true,
fallback: 'path',
}),
},
}| Option | Default | Description |
|---|---|---|
home | false | Root crumb of the document (points at the landing/index of the document). false disables it; { text, link? } is a static crumb (link defaults to the computed landing); 'auto' links to the landing with text = homeText ?? site title ?? base slug; (ctx) => ({ text, link? }) | false is a resolver over BreadcrumbHomeCtx. On the index page itself it renders as the current (unlinked) crumb. |
homeText | site title | Text for home: 'auto' |
prefix | false | Ancestor crumbs before home (for example, a cross-section site root and/or a distribution landing). BreadcrumbHome[] or (ctx) => BreadcrumbHome[]. A prefix crumb whose link matches the current page becomes the current one; consecutive duplicates by link collapse. |
showOnHome | false | Render on layout: home pages as well, or when there is no document context, so prefix can show crumbs on the site root and on landings |
separator | '/' | Separator between crumbs |
showCurrentPage | true | Append the current page as a final (unlinked) crumb |
hideSingle | true | Render nothing when the trail is one crumb or fewer |
fallback | 'none' | 'path' derives crumbs from the URL when the page is missing from the sidebar; 'none' renders nothing |
class | -- | Extra class on the root <nav> |
ariaLabel | 'Breadcrumb' | ARIA label for the landmark |
Disable on a specific page via frontmatter:
---
breadcrumbs: false
---Resolver context
home/prefix functions receive a BreadcrumbHomeCtx:
| Field | Description |
|---|---|
path | Raw route path |
segs | Path segments without the base |
base | Site base ('/', '/alt-server/', ...) |
distro | Base slug ('alt-server'); '' when the base is '/' |
version | First segment when it looks like a version (1.2, 1.2.3, p11) |
sidebarBase | Computed sidebar base ('/11.1/' or '') |
landing | Link to the document landing/index (site base + sidebar base) |
siteTitle | Site title from themeConfig |
pageTitle | Current page title |
Example of a multi-level trail (site root -> distribution landing -> document index -> sidebar path -> current page):
import type { BreadcrumbHomeCtx } from '@ampernic/vitepress-plugin-breadcrumbs'
breadcrumbs: defineBreadcrumbsConfig({
showOnHome: true,
hideSingle: false,
home: (c: BreadcrumbHomeCtx) =>
c.distro
? { text: c.version ? `${c.distro} ${c.version}` : c.distro, link: c.landing }
: false,
prefix: (c: BreadcrumbHomeCtx) => {
const arr = [{ text: 'Home', link: '/' }]
if (c.distro && c.version) arr.push({ text: c.distro, link: `/${c.distro}/` })
return arr
},
})Styling
Styles are scoped and use VitePress CSS variables. Stable classes are available for overrides: .vp-breadcrumbs, .vp-breadcrumbs-list, .vp-breadcrumbs-item, .vp-breadcrumbs-link, .vp-breadcrumbs-current, .vp-breadcrumbs-sep.
License
GPL-3.0-or-later