主题
20260910-0347-breadcrumb-navigation Add breadcrumb navigation with a clickable page at every level
- status: completed
- createdAt: 2026-09-10 03:47
- approvedAt: 2026-09-10 03:55
- relatedTask: 20260910-0347-breadcrumb-navigation
Context
The sidebar was removed in 20260910-0135-product-tree-and-sidebar in favour of index pages. That leaves a page such as /bizplan/product/core/P01-core with no visible route back to the product directory, the product package or the site root, and VitePress's default theme has no breadcrumb.
The site has no custom theme yet: .vitepress/ contains only config.mts. Path depth runs to five segments (bizplan/research/air-key-vendors/keypad/grayhill.md), so a trail needs up to four ancestors plus the current page.
Seventeen directories have no index.md and would otherwise appear as unclickable labels: the 13 product-line directories (core, sense, hub, ac, air-gateway, air-switch, key, studio, mate, view, eye, tag, shared), the three air-key-vendors/ category directories (gateway, switch, keypad) and docs/. data/ and sources/ hold only CSV and PDF assets, contain no page, and never appear in a trail.
Proposal
1. One index page per level
Add 17 index.md files. The 13 product pages carry the product's positioning line (tier, lifecycle, scope, copied from product/index.md) plus its document list, which is also the page the product owner extends when a new document is added to that directory. The three category pages list their vendors; docs/index.md stays English and points at tasks, plans, changelog and architecture.
2. Breadcrumb data built from the file tree
.vitepress/config.mts gains a buildBreadcrumbs() that walks the source tree once at build time and emits { '/bizplan/product/core/': 'YBO Core' , ... } into themeConfig, reading each title from the directory's index.md H1. Adding a document later requires no navigation edit; adding a directory only requires its index.md.
3. Theme component
New .vitepress/theme/index.ts extends the default theme and injects Breadcrumb.vue into the doc-before slot. The component splits page.relativePath, resolves each prefix against the breadcrumb map, and renders 首页 / 产品规格包 / YBO Core / P01-core, with every ancestor a link and the current page as plain text. It renders nothing when frontmatter.layout === 'home'.
4. Link the product index to the product pages
product/index.md section headings currently link straight to specifications; each section gains a link to its product page so the hierarchy is reachable downward as well as upward.
Risks
- A directory added later without an
index.mdwould produce a gap in its children's trails; the build cannot detect this, so it is documented inproduct/index.md's "how to add a product" list. - The custom theme takes over
Layout; future VitePress upgrades may change slot names. The component is small and slot-only, with no styling overrides beyond the trail itself. - Titles come from each
index.mdH1, so renaming a heading silently renames a breadcrumb label. This is intended: one source of truth per level.
Scope
- Added: 17
index.mdfiles,.vitepress/theme/index.ts,.vitepress/theme/Breadcrumb.vue. - Modified:
.vitepress/config.mts,bizplan/product/index.md.
Alternatives
- Render unclickable labels for levels without a page: rejected, the user asked that every level be reachable.
- Restore a per-section sidebar instead: rejected in 20260910-0135; the user chose index-page navigation.
- Hand-maintained breadcrumb map in the config: rejected, it would drift as documents are added.
Execution note
Breadcrumb labels come from a title: frontmatter key where the H1 is too long or contains a slash that would clash with the separator: 商业与产品, 产品规格, 研究报告, PDM 供应商, Air/Key 供应商, Tasks, Plans and the 13 product names. The leaf crumb shows the file name rather than the page title, because titles such as P01 · YBO Core — 智能配电模块系列(Core S / Core M / Core HD) are long and contain slashes, and because documents already reference each other by file name in prose.