Color mode

Breadcrumbs

Build-time breadcrumb navigation derived from the note's slug hierarchy. For every published entry the plugin inserts a <nav> at the top of the rendered HTML and enriches the page with a hierarchical BreadcrumbList JSON-LD schema. No client-side JavaScript is required.

日本語

Overview

breadcrumbs() reads the entry's slug, splits it into segments, and produces a trail that always starts at the site home:

  • Home / folder / sub-folder / Note for folder/sub-folder/note
  • Home / Note for a note at the site root

Intermediate segments are resolved against the manifest first: when the folder has an index note of its own (a note with the folder slug), that note's title is used for the crumb, otherwise the segment is title-cased. The final crumb is the note itself and links to its permalink.

The plugin injects the nav into the manifest entry's HTML. Core synchronizes that HTML with the content the route renders, so the nav appears on generated pages and in feeds.

JSON-LD

breadcrumbs() contributes the hierarchical BreadcrumbList as an entry.headTags <script type="application/ld+json"> so the Site shell can render it in the document <head> (the reference Riebeckite app renders entry.headTags in _renderer.tsx). Item URLs are made absolute against the configured site baseUrl.

When the seo plugin is also enabled it would emit its own two-level BreadcrumbList (Home / Note) inside the article JSON-LD. Pass the page's headTags to the seo extension and it detects the BreadcrumbList this plugin contributed and omits its own placeholder, so the page carries a single BreadcrumbList entity without any Site-side coupling. Set jsonLd: false to stop this plugin from emitting one instead.

Usage

ts
import { defineConfig } from "@riebeckite/core";
import { breadcrumbs } from "@riebeckite/plugin-breadcrumbs";
 
export default defineConfig({
  // ...
  plugins: [breadcrumbs()],
});

Options

Option Type Default Description
homeLabel string site title Home crumb label
className string "rb-breadcrumbs" Root CSS class
ariaLabel string "Breadcrumbs" Accessible nav name
separator string "/" Text between crumbs
jsonLd boolean true Emit the BreadcrumbList script
ts
breadcrumbs({
  homeLabel: "Blog",
  separator: "›",
});

Output

html
<nav class="rb-breadcrumbs" data-breadcrumbs aria-label="Breadcrumbs">
  <ol>
    <li class="rb-breadcrumbs__item">
      <a class="rb-breadcrumbs__link" href="/">Blog</a>
      <span class="rb-breadcrumbs__separator" aria-hidden="true">/</span>
    </li>
    <li class="rb-breadcrumbs__item">
      <a class="rb-breadcrumbs__link" href="/folder">Folder</a>
      <span class="rb-breadcrumbs__separator" aria-hidden="true">/</span>
    </li>
    <li class="rb-breadcrumbs__item">
      <span class="rb-breadcrumbs__current" aria-current="page">Note</span>
    </li>
  </ol>
</nav>

Style

The package ships style.css. Register it like any other plugin stylesheet:

ts
import "@riebeckite/plugin-breadcrumbs/style.css";

Exports

  • breadcrumbs(options?) — plugin factory
  • breadcrumbsPlugin — alias of breadcrumbs
  • resolveBreadcrumbsOptions(options?) — apply option defaults
  • buildBreadcrumbItems({ manifest, entry, config, homeLabel }) — build the trail
  • renderBreadcrumbNav(items, options) — render the navigation HTML
  • buildBreadcrumbJsonLd(config, items) — build the JSON-LD object
  • Types: BreadcrumbsOptions, ResolvedBreadcrumbsOptions, BreadcrumbItem

Limitations

  • The trail is fixed at build time. A full rebuild always recomputes correctly.
  • Only the slug hierarchy is considered; folder ordering from frontmatter or series plugins is intentionally ignored.

See also

History

1 changesCollapseExpand
1 + <!-- Generated from packages/plugins/breadcrumbs/README.md. Do not edit this page directly; edit the package README and run `pnpm docs:sync`. -->
2 +
3 + # Breadcrumbs
4 +
5 + Build-time breadcrumb navigation derived from the note's slug hierarchy. For
6 + every published entry the plugin inserts a `<nav>` at the top of the rendered
7 + HTML and enriches the page with a hierarchical BreadcrumbList JSON-LD schema.
8 + No client-side JavaScript is required.
9 +
10 + [日本語](./breadcrumbs.md)
11 +
12 + ## Overview
13 +
14 + `breadcrumbs()` reads the entry's slug, splits it into segments, and produces a
15 + trail that always starts at the site home:
16 +
17 + - `Home / folder / sub-folder / Note` for `folder/sub-folder/note`
18 + - `Home / Note` for a note at the site root
19 +
20 + Intermediate segments are resolved against the manifest first: when the folder
21 + has an index note of its own (a note with the folder slug), that note's title
22 + is used for the crumb, otherwise the segment is title-cased. The final crumb is
23 + the note itself and links to its permalink.
24 +
25 + The plugin injects the nav into the manifest entry's HTML. Core synchronizes
26 + that HTML with the content the route renders, so the nav appears on generated
27 + pages and in feeds.
28 +
29 + ## JSON-LD
30 +
31 + `breadcrumbs()` contributes the hierarchical BreadcrumbList as an
32 + `entry.headTags` `<script type="application/ld+json">` so the Site shell can
33 + render it in the document `<head>` (the reference Riebeckite app renders
34 + `entry.headTags` in `_renderer.tsx`). Item URLs are made absolute against the
35 + configured site `baseUrl`.
36 +
37 + When the `seo` plugin is also enabled it would emit its own two-level
38 + BreadcrumbList (`Home / Note`) inside the article JSON-LD. Pass the page's
39 + `headTags` to the seo extension and it detects the BreadcrumbList this plugin
40 + contributed and omits its own placeholder, so the page carries a single
41 + BreadcrumbList entity without any Site-side coupling. Set `jsonLd: false` to
42 + stop this plugin from emitting one instead.
43 +
44 + ## Usage
45 +
46 + ```ts
47 + import { defineConfig } from "@riebeckite/core";
48 + import { breadcrumbs } from "@riebeckite/plugin-breadcrumbs";
49 +
50 + export default defineConfig({
51 + // ...
52 + plugins: [breadcrumbs()],
53 + });
54 + ```
55 +
56 + ## Options
57 +
58 + | Option | Type | Default | Description |
59 + | ------ | ---- | ------- | ----------- |
60 + | `homeLabel` | `string` | site title | Home crumb label |
61 + | `className` | `string` | `"rb-breadcrumbs"` | Root CSS class |
62 + | `ariaLabel` | `string` | `"Breadcrumbs"` | Accessible nav name |
63 + | `separator` | `string` | `"/"` | Text between crumbs |
64 + | `jsonLd` | `boolean` | `true` | Emit the BreadcrumbList script |
65 +
66 + ```ts
67 + breadcrumbs({
68 + homeLabel: "Blog",
69 + separator: "›",
70 + });
71 + ```
72 +
73 + ## Output
74 +
75 + ```html
76 + <nav class="rb-breadcrumbs" data-breadcrumbs aria-label="Breadcrumbs">
77 + <ol>
78 + <li class="rb-breadcrumbs__item">
79 + <a class="rb-breadcrumbs__link" href="/">Blog</a>
80 + <span class="rb-breadcrumbs__separator" aria-hidden="true">/</span>
81 + </li>
82 + <li class="rb-breadcrumbs__item">
83 + <a class="rb-breadcrumbs__link" href="/folder">Folder</a>
84 + <span class="rb-breadcrumbs__separator" aria-hidden="true">/</span>
85 + </li>
86 + <li class="rb-breadcrumbs__item">
87 + <span class="rb-breadcrumbs__current" aria-current="page">Note</span>
88 + </li>
89 + </ol>
90 + </nav>
91 + ```
92 +
93 + ## Style
94 +
95 + The package ships `style.css`. Register it like any other plugin stylesheet:
96 +
97 + ```ts
98 + import "@riebeckite/plugin-breadcrumbs/style.css";
99 + ```
100 +
101 + ## Exports
102 +
103 + - `breadcrumbs(options?)` — plugin factory
104 + - `breadcrumbsPlugin` — alias of `breadcrumbs`
105 + - `resolveBreadcrumbsOptions(options?)` — apply option defaults
106 + - `buildBreadcrumbItems({ manifest, entry, config, homeLabel })` — build the trail
107 + - `renderBreadcrumbNav(items, options)` — render the navigation HTML
108 + - `buildBreadcrumbJsonLd(config, items)` — build the JSON-LD object
109 + - Types: `BreadcrumbsOptions`, `ResolvedBreadcrumbsOptions`, `BreadcrumbItem`
110 +
111 + ## Limitations
112 +
113 + - The trail is fixed at build time. A full rebuild always recomputes correctly.
114 + - Only the slug hierarchy is considered; folder ordering from frontmatter or
115 + series plugins is intentionally ignored.
116 +
117 + ## See also
118 +
119 + - [Plugin guide](../reference/plugin-api.en.md)
120 +