@ampernic/vitepress-plugin-breadcrumbs
v0.1.0
Published
Dynamic VitePress-style breadcrumbs derived from the sidebar. Framework-agnostic, configurable, drop-in for any VitePress project.
Maintainers
Readme
@ampernic/vitepress-plugin-breadcrumbs
Dynamic, VitePress-style breadcrumbs derived from the active page's position in the sidebar. Framework-agnostic — no assumptions about your content layout, usable in any VitePress project.
Install
pnpm add @ampernic/vitepress-plugin-breadcrumbsUse
Add the component to a layout slot (commonly 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),
}),
}Configure
Globally via themeConfig.breadcrumbs, or per-instance via props (props
win over config, config wins over defaults). Type the config 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 | Document-root crumb (links to the document landing/index). false = none; { text, link? } = static (link defaults to the resolved landing); 'auto' = link to the landing, text = homeText ?? site title ?? base slug; (ctx) => ({ text, link? }) \| false = resolver built from BreadcrumbHomeCtx. On the index page itself it renders as the (non-link) current crumb. |
| homeText | site title | Text for home: 'auto' |
| prefix | false | Ancestor crumbs prepended before home (e.g. a cross-section site root and/or a distribution landing). BreadcrumbHome[] or (ctx) => BreadcrumbHome[]. Any prefix crumb whose link resolves to the current page becomes the current crumb; consecutive duplicate-link crumbs are merged. |
| showOnHome | false | Also render on layout: home pages / when there is no document context, so a prefix can show breadcrumbs on the site root & landings |
| separator | '/' | String between crumbs |
| showCurrentPage | true | Append current page as last (non-link) crumb |
| hideSingle | true | Render nothing when ≤ 1 crumb |
| fallback | 'none' | 'path' derives crumbs from the URL when the page isn't in the sidebar; 'none' renders nothing |
| class | — | Extra class on the root <nav> |
| ariaLabel | 'Breadcrumb' | ARIA label for the landmark |
Disable on a single page via frontmatter:
---
breadcrumbs: false
---Resolver context
home/prefix functions receive a BreadcrumbHomeCtx:
| Field | Description |
|---|---|
| path | Raw route path |
| segs | Base-stripped path segments |
| base | Site base ('/', '/alt-server/', …) |
| distro | Base slug ('alt-server'); '' when base is '/' |
| version | First segment when it looks like a version (1.2, 1.2.3, p11) |
| sidebarBase | Resolved sidebar base ('/11.1/' or '') |
| landing | Link to the document landing/index (site base + sidebar base) |
| siteTitle | themeConfig site title |
| pageTitle | Current page title |
Example — a multi-level chain (site root → distribution landing → document index → sidebar trail → 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
},
})How it works
- The full ancestor chain is assembled as
prefix → home → sidebar-ancestor groups. Every entry carries a link. - The current page is the last chain crumb whose link resolves to the current route (so the document index/landing renders its own crumb as current); otherwise the current page is appended explicitly.
- Consecutive crumbs pointing at the same page are de-duplicated.
hideSinglethen suppresses a lone crumb (e.g. a bare landing).
The sidebar trail is located inside themeConfig.sidebar (supports the
array form, SidebarMulti, and { base, items } groups), collecting the
ancestor group titles. If the page isn't found and fallback: 'path',
crumbs are derived from the URL segments instead.
Styling
Scoped, uses VitePress CSS variables, and exposes stable classes you can
override: .vp-breadcrumbs, .vp-breadcrumbs-list,
.vp-breadcrumbs-item, .vp-breadcrumbs-link, .vp-breadcrumbs-current,
.vp-breadcrumbs-sep.
License
GPL-3.0-or-later
