Findability - prototype - Hub pages#3223
Draft
florent-leborgne wants to merge 43 commits intonav-v2-sectionsfrom
Draft
Findability - prototype - Hub pages#3223florent-leborgne wants to merge 43 commits intonav-v2-sectionsfrom
florent-leborgne wants to merge 43 commits intonav-v2-sectionsfrom
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>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…ntry When the configured branch (e.g. a prototype/dev branch) has never been published, it won't have a link index entry. Fall back to checking out the branch directly by name rather than blocking the entire build with an error. Cross-link resolution will use whatever entries are available. Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
…fetching For prototype/dev branches (e.g. hub-pages) that have never been deployed and therefore have no link index entry: - RepositoryPublishValidationService: emit warnings instead of errors so validate-assembler doesn't block the build - CrossLinkFetcher.FetchCrossLinks: fall back to main/master cross-link data rather than throwing when the requested branch isn't in the index Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
V2 page links need to register their source files after the V2 tree is built so assembler layouts can position pages that are only surfaced through navigation-v2.yml. Co-Authored-By: GPT-5.5 <noreply@openai.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Assembler builds can process pages from nested TOCs that are not explicitly declared in global navigation, so register those files for positional lookup and let V2 page entries replace them when present. Co-Authored-By: GPT-5.5 <noreply@openai.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Member
|
I took a pass at fixing the previews rather than keeping this as a local-only prototype. Summary of the approach:
What may be temporary:
What I do not think is temporary:
|
Successive refinements after the initial restructure:
- Move product pills from above the H1 into the box's title row, alongside
the "This page applies to" label. Drops ProductPills.cshtml partial and
the page-meta divider; the box is now the single page-top metadata zone.
- Drop the Subscription placeholder row and its CSS.
- Render applies_to entries as plain text + a small "?" icon (CSS-only
reskin of the existing applies-to-popover), comma-separated. The "?"
still triggers the rich tooltip on hover/click. No more "or" separator.
- Sort items so Serverless lands first, then other available items, with
unavailable items at the end (struck-through + dimmed).
- Title typography lifts the row above the rest of the box without
shouting (15px / 700 / ink-dark vs 13px / 600 / grey-80 row labels).
- Stack tooltip description now substitutes {base}/{current}/{base-major}
from the VersioningSystem so the tooltip surfaces the actual range
("Elastic Stack 9.0.0 to 9.4.0...") instead of a static blurb.
- All four Serverless tooltip descriptions append a sentence noting that
Serverless UI/capabilities can differ from versioned Elastic Stack.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The two hub gist HTML files were a stand-in while the V2 nav wiring was unresolved. That's fixed upstream and the docs-content `hub-pages` branch now serves the real hub markdown, so product pills should link to the canonical URLs (`/products/elasticsearch/v9`, `/products/kibana/v9`) instead of the gist previews. The two visual-reference gists are no longer used by any code path. The design handoff gist is still referenced in the PR and remains the human-facing UX/technical write-up. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
florent-leborgne
added a commit
to elastic/docs-content
that referenced
this pull request
May 4, 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.
References docs-content://products/index.md so /products/ resolves to the landing page instead of 404. The landing lists Elasticsearch and Kibana hubs alongside stubs for upcoming products and deployment runbooks. Companion docs-content commit lands the index.md itself on the hub-pages branch.
Stack and Serverless productDescription text changed (Stack interpolates
{base}/{current}/{base-major} from the VersioningSystem; Serverless
appends a sentence about UI/capabilities differing from versioned
Stack), so the popover-data attribute in 40 snapshot fixtures across
ApplicableToComponent.fs, AppliesToRole.fs, and Admonitions.fs needed
to be updated to match. The test fixture's stack VersioningSystem has
base==current==8.0.0, so the substituted string reads "Elastic Stack
8.0.0 to 8.0.0... prior to v8".
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The product pill <a> lives inside <details>/<summary>, so a native click on the pill toggles the box and the link doesn't navigate. `onclick="event.stopPropagation()"` lets the link navigate while the toggle is suppressed. Toggle still works on every other part of the summary (label, chevron, empty space).
Three small fixes triggered by clicking through to hub pages:
- MetadataBox.cshtml: product pill <a> now carries hx-boost="false"
so the body-level hx-boost="true" doesn't intercept the click. The
onclick="event.stopPropagation()" still suppresses the <details>
toggle so the click navigates rather than collapsing the box.
- _Layout.cshtml: hub layout adds an empty <aside id="toc-nav"
hidden> so htmx's hx-select-oob="#content-container,#toc-nav"
swap doesn't fail on missing target when boosting from a regular
page. Hub pages have their own inline {on-this-page} chip, so the
TOC slot stays empty.
- hub.css: drop the grey + dotted page background. It made the page
read inconsistently between full-load and htmx-boosted swap (the
swap leaves the regular layout's white body intact). Hero stays
dark navy; section cards keep their own visual separation.
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 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}:title:,:description:,:icon:,:version:,:versions:(dropdown),:quick-links:,:releases:,:search:. Inline product-icon SVGs forelasticsearch/kibana/observability/security, with single-letter fallback.{on-this-page}{card-group}and{whats-new}on the page that has bothidandtitle.{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.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: newProduct hubstop-bar section with internalpage:references to the docs-content hub markdown (docs-content://products/{kibana,elasticsearch}/v9.md). Wires through the assembler now that the V2-nav fix landed upstream (20a3966d feat(hub-pages): wire hub pages through assembler preview).config/products.yml:Product.Hubfield set to relative slugs (products/elasticsearch/v9,products/kibana/v9) so pills resolve against the site path prefix.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; older majors are stubbed in the version dropdown until last-release hubs (8.19, 7.17) get content.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), with a 28px chevron puck for clear affordance.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.No tests. No unit/snapshot tests for the new directives, view models, or page-title fallback. Should land before promoting to non-prototype.
Out of scope (per the original Findability plan, by design)
{changelog}bundles.🤖 Generated with Claude Code