Findability - prototype - Hub pages#3223
Draft
florent-leborgne wants to merge 66 commits into
Draft
Conversation
Maps each product to an optional hub page URL slug, used by the upcoming
product badge renderer to link page-level product metadata to a 360°
landing page. Elasticsearch and Kibana wired to /hubs/{product}/9.0 for
the prototype; other products leave the field null and render no badge.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a new MarkdownPageLayout.Hub value selected by frontmatter 'layout: hub'. The hub layout shares the section sidebar with regular pages but drops the right-hand TOC and prev/next nav, and renders the markdown body in a full-width <article class="hub-content"> wrapper so hero and card-group directives can manage their own widths. Two placeholder hub pages are wired in at /hubs/elasticsearch/9.0/ and /hubs/kibana/9.0/, listed as hidden entries in docs/_docset.yml. They are reached only via the upcoming Product hubs nav section and the product-badge links; their bodies will be filled by hero/card-group directives in subsequent commits. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Generic, reusable directive that renders a full-bleed hero region with
optional icon, version badge, search box, and quick links. Body content
(typically an H1 plus a short description paragraph) renders inside the
hero, so the page's H1 stays the canonical title.
Title detection in MarkdownFile falls back to descendant H1s when no
top-level H1 is present, so a {hero}-wrapped H1 is still picked up as
the page title without spurious 'no title' warnings.
The wired-up Elasticsearch placeholder hub now drives the hero. Cards
and card-group come in subsequent commits.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
{card-group} is a container with optional :title:, :intro:, 🆔, and
:variant: options that wraps a grid of {link-card} children. {link-card}
is a leaf with a required title argument and 🔗 option, plus an
optional :badge: pill, and renders the directive body as the card
description.
Both are generic enough to be used outside hub pages -- any landing or
section page can render a titled card grid with these.
The Elasticsearch placeholder hub is wired up with three card groups
(What's new in news variant, Install and deploy, Index and ingest data)
to exercise the rendering end to end.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New section in navigation-v2.yml that surfaces the prototype hub pages in the V2 secondary nav. The Elasticsearch and Kibana hubs are wired up as page references; Observability, Security, and the three deployment runbooks are placeholder title leaves until their hub markdown lands. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a ProductBadges partial that renders a clickable pill for each frontmatter product whose Product.Hub field is set, linking to that product's hub page. Skipped on layouts that own their own chrome (hub, landing, archive, full-search). For products without a hub configured, no badge is rendered, so the feature lights up incrementally as more products get hub URLs in products.yml. The mapping is centralized: products.yml is the single source of truth for which products have hubs and where they live. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds hub.css with Tailwind component layer rules for hero, card-group, link-card, and product-badges. The hero is full-bleed dark navy with icon and version chips, content rail constrained to the standard text width. Cards are a responsive 1/2/3-column grid; the news variant collapses to a tighter 1/2-column list. Product badges are subtle grey pills that hover blue. The Kibana hub markdown is filled in with seven sections (What's new, Install and administer, Explore visualize and analyze, Track and respond, AI and automation, Management and developer tools) mirroring the gist prototype. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Index.cshtml skips its auto-rendered H1, product-badges, and applies-to block when the page declares 'layout: hub' so the hero owns the page header and there is no duplicate H1. - hub.css drops the article-level max-width and lets hero/card-group manage their own inner rails. Hero goes edge-to-edge of the content area; card grids open up to a 5xl rail so 3 columns render. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Aligns the hub-page directives with the HTML gist prototypes' DOM and
visual structure. The card / what's new / hero shapes were too thin to
reproduce the gists; this commit replaces them with richer directives:
- {hero}: adds inline product-icon SVGs (kibana/elasticsearch/observability/
security via ProductIcons lookup; first-letter fallback otherwise),
a version pill with status dot, quick-action pill bar, and a release
status line rendered as inline markdown.
- {link-card}: now consumes a YAML body with title/link/description plus a
primary link list and an optional aside (label + inline link list with
middle-dot separators). Adds optional :icon: / :variant: for solution
cards (es / obs / sec accent borders).
- {whats-new}: new directive for the gist's "New" panel -- header with pink
badge, section title, optional release-notes link list on the right,
and items rendered as link rows with title / description / right-side
meta pill.
- {intro}: new directive for the teal-bar tip panel below the hero.
- {on-this-page}: new directive that auto-collects every {card-group} and
{whats-new} on the page (by id+title) and renders a single inline-link
TOC chip.
Both YAML-bodied directives use the existing YamlSerialization static
context (AOT-safe) with new types registered.
The two hub markdown files (Elasticsearch and Kibana) are rewritten to
exercise the full directive set, mirroring the gists' content and shape.
hub.css is rewritten to model the gists' rules with the project's design
tokens.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds the sections that were dropped during the directive rewrite so the hub markdown matches the gist HTML one-to-one: - Elasticsearch: Index and ingest data, Aggregations, Data modeling, Manage data, AI and vector search, Security, Clients and integrations, Reference (8 sections previously missing). - Kibana: Track and respond, AI and automation, Management and developer tools, Reference (4 sections previously missing). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the inert navigation-search web component placeholder with a styled fake search box that matches the gist prototypes (white pill with magnifying-glass icon, contextual placeholder, disabled input). The input is disabled until search is wired up, but visually it's now indistinguishable from the gist. Placeholder text uses the hero :icon: key (e.g. 'Search Kibana docs...'). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Switches .hub-hero-top from flex to a 2-col grid and uses display:contents on .hub-hero-title so its children become direct grid items. The icon vertically centers with the H1 (row 1), and the description spans both columns in row 2 -- matching the gist layout where the description starts at the left edge below the icon row, not hanging-indented next to the H1. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a :versions: option to {hero} taking comma-separated 'Label[=URL]'
entries. When non-empty, the version chip renders as a <details>
dropdown -- click to reveal a menu listing the current version (with a
checkmark) plus each entry. Entries with a URL are clickable links;
entries without a URL render as greyed-out 'soon' rows.
ES 9.4 / Kibana 9.4 hubs are wired with v8 and v7 as disabled entries
so reviewers can see the dropdown shape without yet-built hub pages.
Also bumps Elasticsearch examples to 9.4 and adds a Serverless
release-notes link in the What's new header (matching the Kibana hub).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The {whats-new} directive now accepts a :product: option that looks the
content up in a single source-of-truth file. Authors edit one YAML in
config/, and any page can render that product's panel with a one-line
directive:
:::{whats-new}
:product: kibana
:::
Inline YAML body still works as a fallback / override for one-offs.
The new file is loaded through ConfigurationFileProvider (with embedded-
resource fallback so the binary always has it) and made available to
the directive via BuildContext. Configuration is cached per-build so
multiple {whats-new} blocks share one parse pass.
Both hub markdowns are slimmed down to the one-line shape; their
previous inline data is now in config/whats-new.yml.
Also:
- Switches the What's new item layout to grid with a fixed-width meta
column (130px), so version/date pills line up across rows and
descriptions don't run into them.
- Makes the hero version chip read more clearly as a dropdown: caret is
bigger and lives in a translucent circle, the chip itself has a
brighter idle / hover / open state.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Moves docs/hubs/{es,kibana}/9.0.md to docs/testing/hubs/{es,kibana}/9.0.md
so they appear in the docs-builder docs sidebar under the Testing
group, while still rendering with layout: hub.
- Adds matching folder children in _docset.yml.
- Updates products.yml hub slugs to the new paths so the product badges
link to /testing/hubs/{product}/9.0/.
Also:
- Drops the description truncation in What's new items so long
descriptions wrap onto a second line cleanly under the title (meta
pill stays right-aligned with align-items: baseline).
- Bigger hero version dropdown caret: 28x28 puck with a 16px SVG
chevron (replacing the small ▾ character) so it's clearly a
click target.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Establishes the production-target URL convention. The 'hub' page type
keeps its name internally (frontmatter layout: hub, products.yml
'hub:' field), but the published path segment becomes /products/.
- Files moved: docs/testing/hubs/{...} -> docs/testing/products/{...}
- _docset.yml: folder hubs -> products
- products.yml hub slugs updated
- nav-v2.yml Product hubs section: url /hubs/ -> /products/, page
references updated to docs-builder://testing/products/{...}
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds one syntax/ doc per new directive plus a hub-pages.md overview: - syntax/hub-pages.md -- enables the layout, lists the directive set, shows a full skeleton, documents the product-badge mapping. - syntax/hero.md -- :icon:, :version:, :versions:, :quick-links:, :releases:, :search:; version dropdown shape. - syntax/whats-new.md -- centralized lookup via :product: + the inline YAML override schema. - syntax/intro.md -- markdown body, when to use vs. admonitions. - syntax/on-this-page.md -- auto-collection rules and item ordering. - syntax/card-group.md -- :title:, :intro:, 🆔, fence-depth tip for nested cards, grid layout note. - syntax/link-card.md -- full YAML schema, variants, aside, errors. All seven pages registered alphabetically under docs/syntax/ in _docset.yml. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The hero directive's body convention (first H1 = title, paragraphs = description) was not intuitive. This commit replaces it with explicit :title: (required) and :description: (inline markdown) options. - HeroBlock parses :title: and :description: from options; the body is now ignored. - HeroView renders <h1>@title</h1> and <p>@DescriptionHtml</p> directly, no nested heading-wrapper. CSS targets .hub-hero-title h1 instead of .heading-wrapper. - DescriptionHtml is rendered as inline markdown so links/bold/italic inside the description still work. - MarkdownFile.cs falls back to the first {hero} block's :title: when no document H1 is present, preserving page-title detection. Both hub markdowns are updated. The hero.md and hub-pages.md syntax docs show the new shape. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The assembler can't yet route through the V2 nav for our hub pages
(known limitation -- AssembleSources still wires file output via the V1
toc chain), so the previous in-repo page: references caused
'Could not find ... in navigation' errors during assembler builds.
Replace the section's internal /products/ URL + nested page references
with a single external URL pointing at the Kibana gist preview. The
secondary nav already renders any section whose URL starts with http
as an external link with the ↗ icon (see _SecondaryNav.cshtml).
Effect:
- Assembler build: 0 errors. Top-bar now shows 'Product hubs ↗'.
- Isolated build: unchanged. The real hub pages still render at
/testing/products/{elasticsearch,kibana}/9.0/ in docs-builder's own
meta-docs, which is how reviewers preview them today.
Once the V2 nav-wiring lands upstream, this will revert to internal
section + page references.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Old badges were small underlined pills above the H1 with default <li>
bullets leaking through and ambiguous semantics ('Applies to' clashed
with the existing applies_to lifecycle/version system).
New design:
- Sit inline with the page H1 (.page-title-row flex container, align
baseline + translateY(-0.45em) to land at the H1 x-height).
- Per pill: brand-color accent dot, product name, right-arrow chevron
that slides on hover.
- Hover state: border picks up the brand color, faint background tint,
arrow color and position shift -- reads clearly as 'click to navigate
there'.
- No more SVG product icons in the chip (Elasticsearch tricolor read
like a tiny flag at 14px). The accent dot carries the identity at
any size.
Per-product accents reuse the solution-card brand colors:
elasticsearch=#FEC514, kibana=#F04E98, observability=#0077CC,
security=#00BFB3.
The hub-pages syntax doc now declares products: [elasticsearch, kibana]
in its frontmatter so the new rendering is visible in the docs-builder
docs build.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Until hub pages render through the assembler, product badges now link to the rendered gist previews (htmlpreview.github.io). The gists are the visual reference for the prototype anyway, so badges land on a representative page even when the assembler can't yet wire in our own hub markdown. ProductBadges.cshtml detects absolute URLs (http(s)://) and: - Opens them in a new tab (target=_blank rel=noopener) - Renders an external-link arrow (↗) instead of the chevron - Otherwise keeps the existing internal-pill rendering Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Aligns with the v9/v8 URL convention (v9+ is cumulative for v9 minors and Serverless; older majors are only worth a single 8.19 / 7.17 entry). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
A single white card with a thin grey outline sits below the H1 and renders up to four labeled rows, hidden when empty: - Stack products: hub pills for products with `hub:` set in products.yml. - Stack versions: applies_to.stack badges, plus applies_to.serverless when no deployment is specified. - Deployments: applies_to.deployment badges, plus applies_to.serverless when a deployment is specified (so serverless lands in only one row). - Other products: applies_to.product and per-component applicabilities (EDOT, APM agents, ECCTL, etc.). Three new ApplicabilityBadgePlacement values drive the row-specific collection logic; the existing renderer handles the rest. The hub layout opts out via the Layout frontmatter check, same as before. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ox below
The previous metadata box mixed product pills (navigation) with applies_to
badges (metadata) in one container, which conflated two distinct concerns.
Splitting them gives each a clear role:
- ProductPills.cshtml renders the brand-dotted hub pills above the H1,
styled as nav affordances (dark-grey label, → arrow, no link underline).
- MetadataBox.cshtml renders applies_to data below the H1 in a collapsible
"Requirements" box (Versions / Deployments / Subscription rows). The
Subscription row is a placeholder ("Enterprise") until that metadata
exists. Multiple values within a row are separated by an italic "or".
- A thin divider sits between the H1 and the box to mark the page-top
chrome boundary.
Final styling and placement are a working baseline; refinement is for the
design pass. The structural split is the part that matters and unblocks
adding more page-level metadata systems (e.g. licensing) without piling
loose badges at the page top.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
URL fields in hub directive YAML bodies and options never went through Markdig's link parser, so cross-link resolution, missing-file checks, and link-index emission were all skipped — broken hub links shipped as silent 404s. Adds HubLinkValidator, invoked from each hub block's FinalizeAndValidate for every URL field. It: - resolves declared cross-link schemes via CrossLinkResolver.TryResolve, rewrites the value with the resolved URL, and registers via Build.Collector.EmitCrossLink - emits errors for undeclared schemes (with cursor:/vscode: passthrough) - checks internal absolute paths against the docset source dir in isolated builds (skipped under assembler/codex where cross-docset paths are legal — assembler-aware validation is a follow-up) - honours configured redirects with a warning suggesting the new path Wired only into HeroBlock, LinkCardBlock, and WhatsNewBlock. Surfaces ~40 previously-silent broken cross-link references in docs-content's kibana/elasticsearch hub pages. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
florent-leborgne
added a commit
to florent-leborgne/docs-content
that referenced
this pull request
May 26, 2026
Flat list of Elastic Stack products and Deployment runbooks, matching the sidebar of the prototype gists. Active hubs (Elasticsearch, Kibana) link to their v9 page; the rest are stubbed as "coming soon" so the landing reads as the canonical entry into the hubs section. Pairs with elastic/docs-builder#3223 which now references this page in config/navigation-v2.yml so the Product hubs top-bar URL resolves.
Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # config/navigation-v2.yml # src/Elastic.Documentation.Site/Assets/styles.css # src/Elastic.Markdown/Myst/Directives/DirectiveBlockParser.cs # src/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cs
3 tasks
- Hero directive now renders only icon, title, description, and releases; drop the search box, version dropdown, and quick-link options end to end - Make the hub "on this page" component sticky on desktop - Restore the Products dropdown rendering and scroll-container fix lost in the nav-v2 merge, and remove the deployment-runbook and "soon" stubs Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # src/Elastic.Documentation.Navigation/NavigationItemExtensions.cs # tests/authoring/Applicability/ApplicableToComponent.fs # tests/authoring/Blocks/Admonitions.fs # tests/authoring/Inline/AppliesToRole.fs
- Add md:order-2 to hub <main> so content fills the wide column instead
of collapsing into the sidebar column (matches the default layout).
- Hide the top-bar section dropdown when closed and anchor it under its
summary; let the nav scroll container's overflow go visible while open
so the menu isn't clipped behind the left nav.
- Add a "Find all docs about {product}" eyebrow on hub heroes to signal
the page is a documentation index.
Co-authored-by: Cursor <cursoragent@cursor.com>
Turn the hub indicator into both a label and an escape hatch: keep
"Find all docs about {product}" and add a pill link to the docs home
so readers who land on a product hub can jump to the full docs.
Co-authored-by: Cursor <cursoragent@cursor.com>
theletterf
added a commit
that referenced
this pull request
Jun 25, 2026
Refresh the findability demo branch with the latest hub pages prototype changes from PR #3223 while preserving the demo branch's consolidated nav-v2 state. Co-authored-by: GPT-5.5 <gpt-5.5@openai.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Add Get started and Explore directives, extend the hero with up to three navigation actions, add an upgrade link to What's new, and de-emphasize Get started step numbers. Remove the superseded intro directive. Update syntax docs, example fixtures, and whats-new config to match. Co-authored-by: Cursor <cursoragent@cursor.com>
GHSA-v5pm-xwqc-g5wc flags Microsoft.OpenApi <= 3.5.3 for a high severity circular schema reference issue, surfacing as NU1903 and failing CI restore under TreatWarningsAsErrors. 3.5.4 is the first patched version and matches the bump already on main. Co-authored-by: Cursor <cursoragent@cursor.com>
Use single quotes for the accordion marker content to satisfy the prettier --check step in the npm CI job. Co-authored-by: Cursor <cursoragent@cursor.com>
The cta feature merged from main made MarkdownLayoutViewModel.Cta a required member. PlaceholderPageWriter builds that view model directly and must set it; use the built-in default, matching pages with no cta config. Co-authored-by: Cursor <cursoragent@cursor.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Prototype for the docs Findability initiative -- workstream 2C (Hub Pages). Stacked on top of #2927 (
nav-v2) and #3133 (nav-v2-sections), so review there first.Important
This PR pairs with the
hub-pagesbranch ofelastic/docs-content. The assembler config (config/assembler.yml,narrative.current: hub-pages) clones that branch as the narrative source, so the docs-builder side and the docs-content side build together. Either both land, or both stay paired during review.Thanks to @theletterf for landing the V2 nav-island wiring upstream, which is what made it possible to render real hub pages through the assembler and remove the gist-preview workaround.
Design handoff: hub-pages-design-handoff gist -- UX choices, technical notes, and what's open for proper design to refine.
What it does
Adds first-class support for product hub pages -- product-scoped 360° landing pages -- to docs-builder. A regular markdown page becomes a hub page by setting
layout: hubin frontmatter; the body is then composed from a small set of new MyST directives. Companion docs-contenthub-pagesbranch adds the actual hub markdown for Elasticsearch and Kibana at/products/<product>/v9/.Alongside the hub layout, this PR reworks the page-top metadata model so pills (navigation) and
applies_to(page-level requirements) coexist cleanly without piling loose badges at the top of every page.What landed
New frontmatter layout
layout: hubMarkdownPageLayout.Hubenum value. Selects_Layout.cshtml'sRenderHub()branch -- same chrome as default minus the right-rail TOC and prev/next nav. The body owns the full content-column width so directives can render full-bleed sections.New directives (under
Elastic.Markdown.Myst.Directives.Hub/){hero}:icon:,:title:,:description:,:releases:. Inline product-icon SVGs forelasticsearch/kibana/observability/security, with single-letter fallback. Auto-renders a muted eyebrow above the title: a "Find all docs about {title}" label (signals the page is a documentation index) next to a "Browse all Elastic docs" pill link to the docs home, as an escape hatch to the full docs for readers who landed here looking for something broader.{on-this-page}{card-group}and{whats-new}on the page that has bothidandtitle. Sticky on desktop so it stays visible while scrolling.{intro}{whats-new}:product:from a single source-of-truthconfig/whats-new.yml(any page can render any product's panel with one line); inline YAML body still works as override.{card-group}:title:,:intro:,:id:.{link-card}title,link,description,links[],aside, plus optionalicon/variantfor solution-style accent borders.Note
The hero was deliberately pared back to icon, title, description, and the latest-release line. The earlier search field, version dropdown, and quick-link pills were removed to keep the band clean -- discovery happens through the page body and the top-bar nav rather than hero controls.
The eyebrow (the "Find all docs about {title}" label + "Browse all Elastic docs" link) is a lightweight working baseline. The wording, placement, link target, and styling should be reviewed and refined during proper design -- see the design handoff gist.
Page-top metadata: single "This page applies to" box
The page top is now a single labeled container (
Page/MetadataBox.cshtml) rendered below the H1 on regular pages. Stacking pills +applies_tobadges loose at the page top would be a noisy, unstructured strip; the box gives both systems an explicit place and frees room for future page-level metadata (e.g. licensing).Title row: The bold "This page applies to" label, with product hub pills rendered next to it (one per
products:frontmatter entry whose product hashub:set inconfig/products.yml). Pills carry a brand-color dot, the product name, and a→arrow. They're nav affordances, not body links -- styled dark-grey + semi-bold + no underline (override of.markdown-content a).Below the title row:
applies_to-driven rows, separated by a thin divider. Native<details open>makes the rows collapsible (chevron at far right of the title row, expanded by default).applies_to.stackentries, plusapplies_to.serverlessiff no deployment is specified.applies_to.deploymententries, plusapplies_to.serverlessiff a deployment is specified (so Serverless lands in only one row).Entries render as plain comma-separated text with a small
?icon after each value (CSS-only reskin of the existing<applies-to-popover>-- the rich tooltip behavior is preserved on hover/click). Items are sorted with Serverless first, then other available items, then unavailable items at the end (struck-through and dimmed).Three new
ApplicabilityBadgePlacementmodes (StackVersionsRow,DeploymentsRow,OtherProductsRow) drive the per-row collection logic.Tooltip copy: Stack and Serverless product descriptions in
ProductDescriptions.cswere updated. The Stack description uses{base}/{current}/{base-major}placeholders interpolated from theVersioningSystemat render time (e.g. "This documentation applies to Elastic Stack 9.0.0 to 9.4.0...") so it tracksversions.yml. Serverless descriptions append a sentence noting that Serverless UI/capabilities can differ from versioned Elastic Stack.Note
The current visual language (pill shape, grey-tinted box, divider, chevron position, "?" icon) is a working baseline so we can reason about layout. Final styling, spacing, and placement are for proper design to refine -- see the design handoff gist for the rationale and what's open for iteration.
Centralized "What's new" feed
config/whats-new.yml(embedded as a resource so the binary always carries it).ConfigurationFileProvider(WhatsNewFileproperty) and exposed viaBuildContext-- the same pattern used byproducts.yml.products.<key>->{ title, id, badge, release-links[], items[] }.Page-title detection
MarkdownFile.csfalls back to descendant H1s if no top-level H1 is found, then to{hero}'s:title:option. Hub pages can therefore be purely directive-driven (no body H1) and still get correct page titles.Navigation
config/navigation-v2.yml: newProductstop-bar section in the second slot (right after Guides). The section uses a newdropdown: trueopt-in that renders it as a top-bar dropdown. For the prototype it lists a single Stack products group with Elasticsearch and Kibana -- the only products that currently have hub pages. (The dropdown supports- label:subsection grouping and muted "soon" stubs for- title:items, but none are used here yet.) No/products/landing page -- the dropdown is the discovery surface.dropdown: trueon a section): adds aDropdownflag throughSectionNavV2Item→SectionNavigationNode→NavigationSection, andLayout/_SecondaryNav.cshtmlrenders the section as a<details>/<summary>with a chevron + menu when set. Styled byAssets/secondary-nav-dropdown.css: the menu is hidden when closed and anchored under its summary, and the nav scroll container's overflow opens up while a dropdown is expanded so the menu isn't clipped behind the left nav. The summary is a non-clickable<span>so the whole row toggles the dropdown._Layout.cshtml's hub branch puts the content<main>in the wide column (md:order-2) next to the pages-nav sidebar, and includes an empty<aside id="toc-nav" hidden>so htmx-boosted swaps from regular pages (which select#content-container,#toc-nav) don't bail when navigating into a hub. Hub pages have their own inline{on-this-page}chip, so the slot stays empty.config/products.yml:Product.Hubfield set to relative slugs (products/elasticsearch/v9,products/kibana/v9) so pills resolve against the site path prefix.hx-boost(the body-level htmx default) so click → full native navigation; otherwise htmx swallowed the click before navigation.Source location
products/{elasticsearch,kibana}/v9.md(on thehub-pagesbranch)./products/<product>/<major>/-- e.g.v9,v8. v9+ is cumulative for v9 minors and Serverless, so a single hub covers the active surface.Styling
src/Elastic.Documentation.Site/Assets/markdown/hub.cssandmetadata-box.css, modeled on the visual prototype, using docs-builder design tokens. Imported fromstyles.css.display: contents.<details>/<summary>(no JS).Documentation
docs/syntax/:hub-pages.md-- overview + skeleton + product-badge mappinghero.md,whats-new.md,intro.md,on-this-page.md,card-group.md,link-card.md_docset.ymlalphabetically.How to preview
Preview builds are published automatically for this PR. Open:
The hub pages render through the assembler preview at their target URL shape (
/products/<product>/<major>/), so no local isolated or assembler build is required for review.Known limitations
{link-card}URLs bypass crosslink validation. Because the card body is YAML, the URLs insidelinks[]andaside.links[]aren't seen by the markdown link-validator. They'll render and click, but typos won't fail the build. Worth re-evaluating before this becomes a content authoring path beyond the prototype.{hero}directive emits:releases:URLs verbatim. The hero's inline:releases:values don't go through docs-builder's cross-link or.md-path resolver, so authors have to write full elastic.co URLs there rather than<repo>://...or/path.md. Worth fixing in the directive so authors can use the same conventions everywhere.No tests. No unit/snapshot tests for the new directives, view models, page-title fallback, metadata box, or top-bar dropdown. Should land before promoting to non-prototype.
Out of scope (per the original Findability plan, by design)
{changelog}bundles.🤖 Generated with Claude Code