一个看似简单的面包屑组件,实际需要同时满足三个互不重叠的评判标准——而用户只能看到其中一个。

为什么面包屑比看起来复杂

打开网易新闻 查看精彩图片

开发者常低估面包屑的复杂度。它不只是视觉上的路径指示器,还承担着屏幕阅读器的导航语义,以及搜索引擎结果页的结构化展示。

原文作者用 Breadcrumb.astro 同时处理这三层需求,并设计了一套无配置时的自动回退机制。

核心数据结构很简单:

interface Crumb { label: string; href?: string; }

最后一个 crumb 的 href 为空,表示当前页面不可点击。inverted 用于深色背景反色,noContainer 则跳过外层容器——当面包屑嵌入已受限宽的布局时使用。

组件自动前置"Home" crumb,避免每个调用处重复书写。

自动生成的边界判断

当未传入显式 crumbs 时,组件从 URL 路径推导:

过滤掉字面量 "page" 和纯数字段——/blog/page/2 只生成"Blog",跳过"Page"和"2"。分页是结构细节,不是内容层级。

标签格式化规则:连字符转空格,首字母大写。"why-astro" → "Why Astro"。

作者坦承这不完美:slug "using-mdx" 会渲染成 "Using Mdx",但符合该站点的命名惯例。

搜索引擎的隐形契约

第三层正确性完全不可见:Schema.org 的 BreadcrumbList 结构化标记。

通过 itemscopeitemprop 属性内联在 HTML 中,让搜索引擎能在结果页直接展示面包屑路径。

三层需求,三种受众:用户看视觉,屏幕阅读器解析语义,搜索引擎消费结构化数据。任何一层出错,组件都不算完成。

这种设计思路是否值得引入你的项目?当"够用"和"正确"产生冲突时,你会为不可见的两层额外投入多少成本?