Skip to content

Commit b21dd18

Browse files
docs: add section eyebrow text above page H1 (#45)
* docs: add section eyebrow text above page H1 Show the current topic label (e.g. TERMINAL, AGENTS, ENTERPRISE) as a small uppercase eyebrow above the H1 on every page. Helps orient readers who land directly from search without sidebar context. Derived from starlightSidebarTopics middleware (same data as the header topic nav). Styled with accent blue, xs font, 600 weight, and 0.08em letter-spacing matching the sidebar tier-1 treatment. Co-Authored-By: Oz <oz-agent@warp.dev> * docs: upgrade eyebrow to 2-level breadcrumb (topic + parent group) Walk the sidebar tree to find the immediate parent group of the current page and show it as a breadcrumb: 'AGENTS > THIRD-PARTY CLI AGENTS' instead of just 'AGENTS'. Falls back to topic-only when the page is at the top level of its topic. Truncated to 2 levels max to keep the eyebrow short. Co-Authored-By: Oz <oz-agent@warp.dev> --------- Co-authored-by: Oz <oz-agent@warp.dev>
1 parent abe624e commit b21dd18

1 file changed

Lines changed: 42 additions & 1 deletion

File tree

src/components/CustomPageTitle.astro

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,39 @@ const title = Astro.locals.starlightRoute.entry.data.title;
1313
// an empty paragraph.
1414
const description = Astro.locals.starlightRoute.entry.data.description;
1515
const body = Astro.locals.starlightRoute.entry.body ?? '';
16+
17+
// Eyebrow: a 2-level breadcrumb (e.g. "Agents > Third-Party CLI Agents")
18+
// shown above the H1 to orient readers who land directly from search.
19+
// Level 1 = the current sidebar topic (from starlightSidebarTopics).
20+
// Level 2 = the immediate parent group of the current page in the sidebar
21+
// tree (from starlightRoute.sidebar). Truncated to 2 levels max.
22+
const topics = Astro.locals.starlightSidebarTopics?.topics;
23+
const currentTopic = topics?.find((t: { isCurrent: boolean }) => t.isCurrent);
24+
const topicLabel = currentTopic?.label;
25+
26+
// Walk the sidebar tree to find the parent group of the current page.
27+
type SidebarEntry = { type: string; label: string; isCurrent?: boolean; entries?: SidebarEntry[] };
28+
function findParentGroup(entries: SidebarEntry[], parentLabel?: string): string | undefined {
29+
for (const entry of entries) {
30+
if (entry.type === 'link' && entry.isCurrent) return parentLabel;
31+
if (entry.type === 'group' && entry.entries) {
32+
const found = findParentGroup(entry.entries, entry.label);
33+
if (found) return found;
34+
}
35+
}
36+
return undefined;
37+
}
38+
const sidebar = Astro.locals.starlightRoute?.sidebar as SidebarEntry[] | undefined;
39+
const parentGroup = sidebar ? findParentGroup(sidebar) : undefined;
40+
41+
// Build the eyebrow: "Topic > Parent Group" or just "Topic" if the page
42+
// is at the top level of its topic (no parent group, or parent matches topic).
43+
const eyebrow = topicLabel && parentGroup && parentGroup !== topicLabel
44+
? `${topicLabel} > ${parentGroup}`
45+
: topicLabel;
1646
---
1747

48+
{eyebrow && <p class="page-eyebrow">{eyebrow}</p>}
1849
<div class="page-title-row">
1950
<h1 id="_top">{title}</h1>
2051
<CopyPageButton body={body} title={title} />
@@ -29,10 +60,20 @@ const body = Astro.locals.starlightRoute.entry.body ?? '';
2960
gap: 1rem;
3061
}
3162

63+
.page-eyebrow {
64+
margin-top: 1rem;
65+
margin-bottom: 0.25rem;
66+
font-size: var(--sl-text-xs);
67+
font-weight: 600;
68+
text-transform: uppercase;
69+
letter-spacing: 0.08em;
70+
color: var(--sl-color-text-accent);
71+
}
72+
3273
.page-title-row h1 {
3374
flex: 1;
3475
min-width: 0;
35-
margin-top: 1rem;
76+
margin-top: 0;
3677
font-size: var(--sl-text-h1);
3778
line-height: var(--sl-line-height-headings);
3879
font-weight: 700;

0 commit comments

Comments
 (0)