Demo findability prototypes together#3256
Conversation
Adds a new `navigation-v2.yml`-driven sidebar behind the `nav-v2`
feature flag (enabled by default in dev/preview environments).
- New YAML format: label sections (non-clickable headings), toc entries
that resolve to existing navigation nodes at their original URL paths,
page crosslinks, and title-only placeholder (disabled) links
- `SiteNavigationV2` extends `SiteNavigation`, passes the original
nav file to the base constructor so content URLs are unchanged; builds
a separate `V2NavigationItems` tree for sidebar rendering
- `GlobalNavigationHtmlWriter` detects `SiteNavigationV2` and returns
the same full V2 nav HTML (cached once) for every page
- `_TocTreeNavV2.cshtml` renders labels as `<span>`, placeholders as
`aria-disabled` anchors, folders/leaves same as V1
- `pages-nav-v2.ts` adds accordion collapse (open one section → others
collapse) and current-page marking with no auto-expand
- Feature flag key normalisation: assembler.yml uses `NAV_V2` (underscore)
but lookup uses `nav-v2` (hyphen); fixed by calling `featureFlags.Set`
which normalises via `ToLowerInvariant().Replace('_', '-')`
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ShortId.Create("label") always produced the same SHA256 hash, so all
8 label checkboxes shared id="v2-label-1ACA80E8". Every <label for="">
targeted the first checkbox, making only "Get Started" expandable.
Fix: include the label text in the hash — ShortId.Create("label", label).
Also updates nav-v2-status.md to reflect verified accordion behaviour.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…d labels)
Translates the team's proposed information architecture into the V2 nav:
Top-level labels:
• Elasticsearch fundamentals (get-started + placeholder concepts)
• Install, deploy, and administer (deploy-manage + cloud-account)
• The Elasticsearch Platform (container for nested labels)
• Solutions and project types (solutions)
• Reference (elasticsearch + kibana)
• Troubleshooting (troubleshoot)
"The Elasticsearch Platform" has three nested labels:
• Ingest and manage data → toc: manage-data
• Search, visualize, and analyze → toc: explore-analyze
• AI and machine learning → title: placeholders (content lives in
explore-analyze today; dedicated toc roots needed to wire up)
Nested labels work with no code changes — the YAML parser, SiteNavigationV2
builder, and _TocTreeNavV2 partial already recurse through children at any
depth. The Razor partial applies level-aware styling (font-semibold at
level 0, lighter weight at depth 1+).
Also documents the proposed IA mapping and content split analysis
in nav-v2-status.md.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Labels at any depth are now unconditionally expanded — no checkbox, no chevron, children always visible. This applies to both top-level labels (Elasticsearch fundamentals, The Elasticsearch Platform, etc.) and nested labels (Ingest and manage data, Search/visualize, AI/ML). _TocTreeNavV2.cshtml: for LabelNavigationNode, removed the peer div / checkbox / chevron pattern; render a plain <span> heading followed by an always-visible <ul> of children. Removed data-v2-accordion from label <li> elements since labels no longer participate in accordion. TOC folder nodes (INodeNavigationItem) retain their existing checkbox-driven expand/collapse toggle unchanged. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Verified behaviours: labels always expanded (no toggle), nested labels same, placeholders render as disabled, TOC folders still toggle, accordion scoped to TOC siblings - Mark nested label support as done - Correct build/serve commands to dotnet run invocations - Note LabelNavigationNode.ExpandedByDefault is now unused Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Level-1 labels (top-level sections): font-semibold text-sm text-ink — bold, 14px, full ink colour. Level-2+ labels (sub-section dividers): text-[10px] font-semibold uppercase tracking-widest text-ink/50 — all-caps, 10px, wide letter-spacing, 50% opacity. This is the standard sidebar sub-group treatment (VS Code, Linear, Notion style) and makes the hierarchy immediately legible at a glance. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Level-1 label text: text-xs uppercase tracking-widest font-semibold text-ink — same small-caps treatment as level-2 but full ink colour, making them clearly structural dividers not clickable links - Level-1 label <li>: border-t border-grey-20 pt-4 mt-4 to draw a thin horizontal rule between each top-level section; first: variant removes the border/padding from the first item Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Was text-[10px] text-ink/50 — too small and too dim to read comfortably. Now text-xs (12px) text-ink/65 — same small-caps uppercase treatment, clearly subordinate to level-1 but readable at a glance. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces `GroupNavV2Item` — a YAML `group:` item that renders as an expandable folder with a disabled (cursor-not-allowed) link and a chevron toggle. Unlike `label:` (always-expanded section heading), `group:` behaves like a regular TOC folder but with no real URL. Changes: - `NavigationV2File.cs`: add `GroupNavV2Item` record + `group:` YAML parsing - `PlaceholderNavigationNode.cs`: new nav node implementing INodeNavigationItem - `SiteNavigationV2.cs`: `CreateGroup` builder (mirrors `CreateLabel`) - `_TocTreeNavV2.cshtml`: render PlaceholderNavigationNode as disabled folder - `navigation-v2.yml`: replace `toc: manage-data` in "Ingest and manage data" with the full "Ingest or migrate: bring your data into Elasticsearch" tree (placeholder titles only; no toc/page refs yet) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Translates the complete card-sort JSON into navigation-v2.yml using group:/title: placeholders throughout. All 6 top-level labels are populated with the full proposed IA structure — no toc/page refs yet. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Switch NavV2Deserializer from DeserializerBuilder to StaticDeserializerBuilder — our NavV2FileYamlConverter parses manually via parser events so the static context is sufficient; fixes IL3050/IL2055 AOT errors in the native build - Remove unused `$` import from pages-nav-v2.ts; fixes ESLint @typescript-eslint/no-unused-vars error in the npm check Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- SiteNavigationV2: replace foreach loop in BuildV2Items with Select/Where/Cast/ToList chain - AssemblerBuildService: combine nested ifs into single && condition Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add PageCrossLinkLeaf — resolves a page: URI to a canonical URL using sitePrefix + URI host + path (minus .md extension). Renders as a real clickable link via the existing ILeafNavigationItem branch in the Razor partial, distinct from PlaceholderNavigationLeaf (disabled). Also wires page: candidates into the "Ingest or migrate" section of navigation-v2.yml, replacing title: placeholders where content exists. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ationV2
The pattern `{ Page: var page }` combined with the prior `{ Page: null }` arm
already guarantees `page` is non-null when this arm matches.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Walk up the DOM from the matched link and check each ancestor collapsible checkbox so the sidebar reveals the active page location when navigating directly to a URL. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The file-writing pipeline (GlobalNavigationPathProvider) uses NavigationTocMappings populated from navigation.yml before SiteNavigationV2 is constructed, so path prefix overrides in the navigation model don't reach the output files. Reverted to reusing V1 nodes directly. Added a URL scheme section to the PR description explaining the architectural boundary and the intended final design. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…tries Replace all placeholder title:/group: items in the Reference label with toc: roots derived from navigation.yml. Remove the redundant group: Elastic Cloud on Kubernetes (covered by Cloud group) and drop the [XREF] ECCTL cross-reference. Numeral formatting wired as a page: cross-link since it lives under explore-analyze, not reference. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace placeholder title: items with real page: entries pointing to individual troubleshoot pages in docs-content. Keep the five-group structure (Elasticsearch, Kibana, Observability, Security, Ingestion tools) rather than collapsing to a single toc: root. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…roubleshooting nav updates - Add PageFolderNavigationNode: a group node with a real clickable URL, used when a group: entry in navigation-v2.yml carries a page: key - Extend GroupNavV2Item with optional Uri? Page and wire YAML parser - Update SiteNavigationV2.CreateGroup to emit PageFolderNavigationNode when a page is present, PlaceholderNavigationNode otherwise - Expand "Migrating your Elasticsearch data" placeholder into a real page-folder group (migrate.md as parent, four child pages beneath) - Comment out Reference and Troubleshooting labels in navigation-v2.yml Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…-folder groups When a group: item also has a page: key, the old order caused the page: branch to fire first, returning a raw PageNavV2Item leaf instead of a GroupNavV2Item. Swap check order so group: always wins when present. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Each PlaceholderNavigationLeaf and PlaceholderNavigationNode now gets a
computed URL (/{sitePrefix}/_placeholder/{hash}) and a corresponding
generated stub page (H1 title + "coming soon" paragraph) with the full
site chrome including the V2 nav sidebar.
PlaceholderPageWriter walks the V2 nav tree after the main build and
writes one HTML file per unique placeholder URL to the output directory.
The nav sidebar now renders placeholder links as clickable greyed hrefs
instead of aria-disabled spans — cursor-not-allowed is removed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… assets env.PathPrefix is "docs" (no leading slash); UrlPathPrefix must be "/docs" so Static() generates absolute paths like /docs/_static/styles.css instead of relative paths that resolve incorrectly from /_placeholder/HASH/ depth. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… sections (#2957) Replace placeholder title: entries with full-depth page: references for three navigation sections: - **Explore and visualize**: Discover, Dashboards, Panels & visualizations (Lens, Maps, Canvas, Graph, Legacy editors), Find and organize content. Reordered to: Learn → Discover → Dashboards → Panels → Find & organize. - **Share, alert, and automate** (renamed from "Alert and trigger actions"): Reporting and sharing (moved from Explore), Workflows (full depth incl. triggers, steps, data handling), Alerting (alerts + full Watcher tree), Cases. - **AI and machine learning**: ML/NLP (anomaly detection, data frame analytics, NLP, ML in Kibana), AI framework (Elastic Inference, Agent Builder with full tool/agent/programmatic-access tree, AI chats, LLM guides), AI agent skills. All 313 page: entries include title: overrides derived from each file's navigation_title frontmatter field or cleaned H1 heading. Both "Explore and visualize" and "Share, alert, and automate" groups now link to new overview landing pages added in docs-content (hidden pages, merged via elastic/docs-content#5601). Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
#2958) Replace placeholder title: entries with full-depth page: references for the Solutions and project types section: - Solutions overview linked to existing solutions/index.md - Elasticsearch solution: full hierarchy (Get started, Playground, AI Assistant, Query rules, Search Applications, Add-ons) - Observability solution: full hierarchy (Get started, Applications/APM, Synthetics, Logs, Infrastructure, Streams, Incident management, Cloud, AI for Observability) - Security solution: full hierarchy (Get started, AI for Security, Detections and alerts, Configure/Manage Elastic Defend, Cloud Security, Investigation tools, Dashboards, Entity analytics) - Search use case excluded per the new IA design All page: entries include title: overrides from navigation_title or H1. Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # src/Elastic.Documentation.Site/Navigation/IsolatedBuildNavigationHtmlWriter.cs # src/Elastic.Documentation.Site/Navigation/NavigationViewModel.cs # src/Elastic.Documentation.Site/Navigation/_TocTree.cshtml # src/Elastic.Documentation.Site/Navigation/_TocTreeNav.cshtml
Co-authored-by: Cursor <cursoragent@cursor.com> # Conflicts: # config/navigation-v2.yml # src/Elastic.Documentation.Site/Navigation/NavigationViewModel.cs
Align top-level label spacing and active-row visuals with the latest nav spec, and make the right-side On this page links/border keep the nav text color on hover. Co-authored-by: Cursor <cursoragent@cursor.com>
Switch sidebar utility links and the On this page heading container to the body font stack and normal weight to match the rest of the navigation typography. Co-authored-by: Cursor <cursoragent@cursor.com>
Keep 12px top padding on the first nav-v2 tree item by default, and only collapse it to 0 when navigation search is present in sticky chrome. Co-authored-by: Cursor <cursoragent@cursor.com>
Ensure folder rows stay expanded on first re-activation click and introduce an explicit immediate-parent active marker while preserving full ancestor state styling. Co-authored-by: Cursor <cursoragent@cursor.com>
This reverts commit 6d5be8b. The Products dropdown is the discovery surface, so /products/ doesn't need a placeholder landing page. Drops the index entry from the Products section's children entirely, and switches the dropdown summary in _SecondaryNav.cshtml from an <a> to a non-clickable <span> so clicking the title row toggles the dropdown instead of trying to navigate to a non-existent landing.
The secondary-nav-dropdown-group-label was rendering as uppercase with letter-spacing (UI-pattern look), which Florent didn't want. Plain title case at 12px / weight 700 / grey-80 reads cleaner and matches the rest of the menu typography.
Use the V2 navigation tree for footer neighbors so Guides pages remapped through navigation-v2.yml do not fall back to unrelated V1 positions. Co-Authored-By: GPT-5.5 <noreply@openai.com> Co-authored-by: Cursor <cursoragent@cursor.com>
Replaces section-based layout with a tab-driven design: - Search-first hero with no subtitle - Platform / Solutions / Deploy tabs with product cards - Streamlined Get started section (concepts, local, cloud trial) - Flat all-products grid categorized by platform, solutions, deploy, ingest tools, query languages, APM agents, and developer tools Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…der into landing-page/prototype
|
@theletterf I was surfing through https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3256. Is the search bar in the middle of the page, just below the Elastic documentation title, still an option? |
|
@alaudazzi If you mean the landing / home, that's a question for @KOTungseth and @itsalexcm |
# Conflicts: # config/navigation-v2.yml # docs/_docset.yml
{hero}, {link-card}, and {whats-new} emit YAML body URLs verbatim
into <a href> attributes — they don't go through Markdig's link
resolver. So root-relative URLs like \`/deploy-manage/...\` landed
on the page as-is and broke under the \`/docs/\` path prefix the
assembler builds with.
Add a HubUrl.Prefix helper that prepends the site path prefix to
root-relative URLs (leaves absolute http/https/mailto and anchors
alone, and won't double-prefix). Pass block.Build.UrlPathPrefix into
the three view models, and call Model.PrefixUrl(...) in the cshtml
where hrefs are emitted.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The body has hx-boost=\"true\" hx-swap=\"none\" so boosted clicks
need an explicit hx-select-oob to swap anything. Hub-directive
links don't carry those attributes — clicks pushed the URL but
swapped no content, so the page appeared to just scroll to the top.
Add hx-boost=\"false\" to every <a> in {hero}, {link-card}, and
{whats-new} so they fall back to native navigation. Same fix
already in place for the page-top product pills.
Hub directives ({hero}, {link-card}, {whats-new}) emit URLs verbatim
into <a href>. Authors naturally write .md file paths (matching how
body markdown works) but the assembler serves clean URLs without
.md. So /reference/elasticsearch-clients/index.md 404'd on the
assembled site.
HubUrl.Prefix now strips trailing .md and /index.md before
prepending the site path prefix. Anchors are preserved.
Also fixes 4 source URLs whose docs-content folder names differ
from the slug the assembler serves (e.g. /release-notes/elastic-
security/ -> /release-notes/security), and the wrong fleet-
integrations target.
All 193 internal hub-page links now resolve (76/76 elasticsearch,
117/117 kibana, validated against the local assembler serve).
The RegisterV2PageLookups machinery from d556dff was dropped when nav-v2-sections was merged into hub-pages. Without it, V2 page: entries referencing files in unseen child TOCs are shadowed by the V1 TableOfContentsNavigation registration, breaking positional layout for those pages. Restores the original logic and uses Remove + Add so V2 entries override V1 toc entries on collision. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Introduces a new visual direction: - Gradient hero with two prominent destination cards (Elastic fundamentals and Elasticsearch) above the fold - Search bar moved into the hero - Quick start section for new users (local install + cloud trial) - What's new strip showing latest release notes - Four-column all-products index (platform, solutions, deploy, ingest, query languages, APM agents, developer tools) - Community/help strip (forums, training, docs issues) - CSS scoped to .landing-page to avoid global style leakage Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Swap divs for semantic HTML: header, main, section, article, nav, search, time - Add aria-label attributes to hero, search, cards, and product nav - Add aria-hidden to decorative SVGs - Simplify help strip to single "Report a docs issue" item 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>
Replace the 'Elastic Fundamentals' link locator with the new 'Get started' hero CTA, scoped to .landing-hero, since the redesigned landing page no longer exposes the prior label.
There was a problem hiding this comment.
Actionable comments posted: 5
♻️ Duplicate comments (1)
src/Elastic.Markdown/Layout/_LandingPage.cshtml (1)
39-320:⚠️ Potential issue | 🟠 Major | 🏗️ Heavy liftScope all landing-page CSS selectors to avoid cross-page style bleed.
From Line 39 onward, selectors are mostly global class selectors (
.landing-hero,.hero-card,.quickstart, etc.). If the same class names appear elsewhere, these rules will leak outside this page. Prefix these with.landing-pageconsistently (including inside media queries).Proposed scoping pattern
- .landing-hero { + .landing-page .landing-hero { background: linear-gradient(180deg, `#EEF4FF` 0%, `#F7FAFF` 60%, `#FFFFFF` 100%); } - .hero-card:hover .card-cta svg { transform: translateX(3px); } + .landing-page .hero-card:hover .card-cta svg { transform: translateX(3px); } - @@media (max-width: 900px) { - .hero-cards { grid-template-columns: 1fr; } + @@media (max-width: 900px) { + .landing-page .hero-cards { grid-template-columns: 1fr; } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@src/Elastic.Markdown/Layout/_LandingPage.cshtml` around lines 39 - 320, The CSS uses global class selectors (e.g., .landing-hero, .hero-card, .quickstart, .landing-main, .news-grid, .all-products-grid, .help-strip, .hero-search-wrap, .landing-section-header) which can bleed into other pages; scope every rule by prefixing the selectors with a page wrapper class such as .landing-page (e.g., .landing-page .landing-hero, .landing-page .hero-card, .landing-page .hero-card.primary::before, etc.), update all compound and nested selectors and pseudo-elements accordingly, and ensure the media queries use the same prefixed selectors and retain their `@media` rules so styles remain page-scoped without changing specificity.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/Elastic.Documentation.Site/Layout/_SecondaryNav.cshtml`:
- Around line 23-31: The dropdown summary rendering omits the navTab.Url so
dropdown tabs no longer link to their section page; update the block handling
navTab.Dropdown in _SecondaryNav.cshtml to render an anchor using navTab.Url
(e.g., wrap the label/chevron in an <a> or emit an <a href="@navTab.Url">) and
preserve appropriate aria attributes/classes (secondary-nav-dropdown-label /
secondary-nav-dropdown-chevron), and ensure the subsequent logic that uses
continue for hidden index leaves does not skip emitting the index link when
navTab.Url is present.
In `@src/Elastic.Markdown/Layout/_TableOfContents.cshtml`:
- Line 33: Multiple anchor elements in _TableOfContents.cshtml use
target="_blank" without rel attributes (e.g., the anchor with
href="@Model.MarkdownUrl" and the other anchors on the same block), so update
each <a ... target="_blank"> to include rel="noopener noreferrer" to harden
opener isolation; find the anchors that reference Model.MarkdownUrl and the
other external links in the same block (lines mentioned) and add the rel
attribute to each.
In `@tests/Navigation.Tests/Assembler/SiteNavigationTests.cs`:
- Around line 385-386: Rename the test method
SiteNavigationV2PageEntriesUseV2OrderForPrevNext to follow
Method_Scenario_Expected naming; update its name to
SiteNavigationV2_PageEntriesWithV2Navigation_UseCorrectPrevNextOrder (and adjust
any references/usages accordingly), ensuring the test attribute [Fact] remains
and any test discovery or doc comments are updated to reflect the new name.
- Around line 461-462: Rename the test method
SiteNavigationResolvesFilesFromUnseenChildTocs to follow the
Method_Scenario_Expected pattern (e.g.,
SiteNavigation_FilesFromUnseenChildTocs_ResolvesCorrectly) and update any
references/usages accordingly; keep the [Fact] attribute and method body
unchanged, just change the method identifier so it complies with the naming
convention.
- Around line 310-311: Rename the test method
SiteNavigationV2PageEntriesResolveFilesFromUnseenChildTocs to follow the
Method_Scenario_Expected convention; change its identifier to
SiteNavigationV2_PageEntriesForUnseenChildTocs_ResolvesFiles and update any
references/usages (e.g., in test attributes or callers) to the new name so the
test compiles and runs under the expected naming convention.
---
Duplicate comments:
In `@src/Elastic.Markdown/Layout/_LandingPage.cshtml`:
- Around line 39-320: The CSS uses global class selectors (e.g., .landing-hero,
.hero-card, .quickstart, .landing-main, .news-grid, .all-products-grid,
.help-strip, .hero-search-wrap, .landing-section-header) which can bleed into
other pages; scope every rule by prefixing the selectors with a page wrapper
class such as .landing-page (e.g., .landing-page .landing-hero, .landing-page
.hero-card, .landing-page .hero-card.primary::before, etc.), update all compound
and nested selectors and pseudo-elements accordingly, and ensure the media
queries use the same prefixed selectors and retain their `@media` rules so styles
remain page-scoped without changing specificity.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Enterprise
Run ID: 424e78de-47e1-4d77-b216-38c08fca1494
📒 Files selected for processing (30)
config/assembler.ymlconfig/navigation-v2.ymldocs/_docset.ymlsrc/Elastic.Documentation.Configuration/Elastic.Documentation.Configuration.csprojsrc/Elastic.Documentation.Configuration/Toc/NavigationV2File.cssrc/Elastic.Documentation.Links/CrossLinks/CrossLinkFetcher.cssrc/Elastic.Documentation.Navigation/V2/NavigationSection.cssrc/Elastic.Documentation.Navigation/V2/SectionNavigationNode.cssrc/Elastic.Documentation.Navigation/V2/SiteNavigationV2.cssrc/Elastic.Documentation.Site/Assets/pages-nav-v2.tssrc/Elastic.Documentation.Site/Assets/secondary-nav-dropdown.csssrc/Elastic.Documentation.Site/Assets/styles.csssrc/Elastic.Documentation.Site/Layout/_SecondaryNav.cshtmlsrc/Elastic.Documentation.Site/Navigation/IsolatedBuildNavigationHtmlWriter.cssrc/Elastic.Documentation.Site/Navigation/NavigationViewModel.cssrc/Elastic.Documentation.Site/Navigation/_TocTree.cshtmlsrc/Elastic.Documentation.Site/Navigation/_TocTreeNav.cshtmlsrc/Elastic.Documentation.Site/_ViewModels.cssrc/Elastic.Documentation.Site/synthetics/journeys/navigation-test.journey.tssrc/Elastic.Markdown/HtmlWriter.cssrc/Elastic.Markdown/IO/MarkdownFile.cssrc/Elastic.Markdown/Layout/_LandingPage.cshtmlsrc/Elastic.Markdown/Layout/_TableOfContents.cshtmlsrc/Elastic.Markdown/Myst/Directives/DirectiveBlockParser.cssrc/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cssrc/Elastic.Markdown/Page/Index.cshtmlsrc/Elastic.Markdown/Page/IndexViewModel.cssrc/services/Elastic.Documentation.Assembler/Building/AssemblerBuildService.cssrc/services/Elastic.Documentation.Assembler/Navigation/GlobalNavigationHtmlWriter.cstests/Navigation.Tests/Assembler/SiteNavigationTests.cs
✅ Files skipped from review due to trivial changes (2)
- src/Elastic.Documentation.Configuration/Elastic.Documentation.Configuration.csproj
- src/Elastic.Markdown/HtmlWriter.cs
🚧 Files skipped from review as they are similar to previous changes (21)
- src/Elastic.Markdown/Page/IndexViewModel.cs
- src/Elastic.Markdown/Myst/Directives/DirectiveBlockParser.cs
- src/Elastic.Documentation.Site/Navigation/NavigationViewModel.cs
- src/Elastic.Documentation.Site/_ViewModels.cs
- src/Elastic.Markdown/IO/MarkdownFile.cs
- src/Elastic.Documentation.Site/Navigation/IsolatedBuildNavigationHtmlWriter.cs
- src/Elastic.Documentation.Navigation/V2/NavigationSection.cs
- src/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cs
- src/Elastic.Documentation.Site/Navigation/_TocTreeNav.cshtml
- docs/_docset.yml
- src/Elastic.Documentation.Site/Navigation/_TocTree.cshtml
- src/Elastic.Documentation.Links/CrossLinks/CrossLinkFetcher.cs
- src/services/Elastic.Documentation.Assembler/Building/AssemblerBuildService.cs
- src/Elastic.Documentation.Navigation/V2/SectionNavigationNode.cs
- config/assembler.yml
- src/Elastic.Markdown/Page/Index.cshtml
- src/Elastic.Documentation.Configuration/Toc/NavigationV2File.cs
- src/Elastic.Documentation.Site/Assets/pages-nav-v2.ts
- src/services/Elastic.Documentation.Assembler/Navigation/GlobalNavigationHtmlWriter.cs
- src/Elastic.Documentation.Navigation/V2/SiteNavigationV2.cs
- src/Elastic.Documentation.Site/Assets/styles.css
| else if (navTab.Dropdown) | ||
| { | ||
| <details class="secondary-nav-dropdown"> | ||
| <summary class="inline-flex items-center gap-1 cursor-pointer select-none"> | ||
| <span class="secondary-nav-dropdown-label">@navTab.Label</span> | ||
| <svg width="11" height="11" viewBox="0 0 16 16" fill="none" aria-hidden="true" class="secondary-nav-dropdown-chevron"> | ||
| <path d="M4 6l4 4 4-4" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> | ||
| </svg> | ||
| </summary> |
There was a problem hiding this comment.
Dropdown tabs no longer link to their section page.
The dropdown summary only renders the label and chevron, but never emits navTab.Url. That breaks section-landings for dropdown tabs, and it’s amplified by the later continue that skips the hidden index leaf because it assumes the summary already links there.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/Elastic.Documentation.Site/Layout/_SecondaryNav.cshtml` around lines 23 -
31, The dropdown summary rendering omits the navTab.Url so dropdown tabs no
longer link to their section page; update the block handling navTab.Dropdown in
_SecondaryNav.cshtml to render an anchor using navTab.Url (e.g., wrap the
label/chevron in an <a> or emit an <a href="@navTab.Url">) and preserve
appropriate aria attributes/classes (secondary-nav-dropdown-label /
secondary-nav-dropdown-chevron), and ensure the subsequent logic that uses
continue for hidden index leaves does not skip emitting the index link when
navTab.Url is present.
| <ul class="mt-4 hidden md:flex items-center lg:block gap-4"> | ||
| <li class="view-as-markdown hidden lg:block lg:not-first:mt-1"> | ||
| <a href="@Model.MarkdownUrl" class="link text-sm" target="_blank"> | ||
| <a href="@Model.MarkdownUrl" class="link text-sm font-body font-normal" target="_blank"> |
There was a problem hiding this comment.
Add rel="noopener noreferrer" to external _blank links.
These links open a new tab but don’t set rel, which weakens opener isolation and link hardening. Please add rel="noopener noreferrer" on each target="_blank" anchor in this block.
Suggested patch
-<a href="@Model.MarkdownUrl" class="link text-sm font-body font-normal" target="_blank">
+<a href="@Model.MarkdownUrl" class="link text-sm font-body font-normal" target="_blank" rel="noopener noreferrer">
...
-<a href="@Model.ReportIssueUrl" class="link text-sm font-body font-normal" target="_blank">
+<a href="@Model.ReportIssueUrl" class="link text-sm font-body font-normal" target="_blank" rel="noopener noreferrer">
...
-<a href="@Model.GithubEditUrl" class="link text-sm font-body font-normal" target="_blank">
+<a href="@Model.GithubEditUrl" class="link text-sm font-body font-normal" target="_blank" rel="noopener noreferrer">
...
-<a href="https://www.elastic.co/docs/contribute-docs/" class="link text-sm font-body font-normal" target="_blank">
+<a href="https://www.elastic.co/docs/contribute-docs/" class="link text-sm font-body font-normal" target="_blank" rel="noopener noreferrer">Also applies to: 43-43, 54-54, 65-65
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@src/Elastic.Markdown/Layout/_TableOfContents.cshtml` at line 33, Multiple
anchor elements in _TableOfContents.cshtml use target="_blank" without rel
attributes (e.g., the anchor with href="@Model.MarkdownUrl" and the other
anchors on the same block), so update each <a ... target="_blank"> to include
rel="noopener noreferrer" to harden opener isolation; find the anchors that
reference Model.MarkdownUrl and the other external links in the same block
(lines mentioned) and add the rel attribute to each.
| [Fact] | ||
| public void SiteNavigationV2PageEntriesResolveFilesFromUnseenChildTocs() |
There was a problem hiding this comment.
Test method name violates naming convention.
As per coding guidelines, test methods should follow the Method_Scenario_Expected pattern. Consider renaming to SiteNavigationV2_PageEntriesForUnseenChildTocs_ResolvesFiles.
As per coding guidelines: "Test method naming convention: Method_Scenario_Expected."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/Navigation.Tests/Assembler/SiteNavigationTests.cs` around lines 310 -
311, Rename the test method
SiteNavigationV2PageEntriesResolveFilesFromUnseenChildTocs to follow the
Method_Scenario_Expected convention; change its identifier to
SiteNavigationV2_PageEntriesForUnseenChildTocs_ResolvesFiles and update any
references/usages (e.g., in test attributes or callers) to the new name so the
test compiles and runs under the expected naming convention.
| [Fact] | ||
| public void SiteNavigationV2PageEntriesUseV2OrderForPrevNext() |
There was a problem hiding this comment.
Test method name violates naming convention.
As per coding guidelines, test methods should follow the Method_Scenario_Expected pattern. Consider renaming to SiteNavigationV2_PageEntriesWithV2Navigation_UseCorrectPrevNextOrder.
As per coding guidelines: "Test method naming convention: Method_Scenario_Expected."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/Navigation.Tests/Assembler/SiteNavigationTests.cs` around lines 385 -
386, Rename the test method SiteNavigationV2PageEntriesUseV2OrderForPrevNext to
follow Method_Scenario_Expected naming; update its name to
SiteNavigationV2_PageEntriesWithV2Navigation_UseCorrectPrevNextOrder (and adjust
any references/usages accordingly), ensuring the test attribute [Fact] remains
and any test discovery or doc comments are updated to reflect the new name.
| [Fact] | ||
| public void SiteNavigationResolvesFilesFromUnseenChildTocs() |
There was a problem hiding this comment.
Test method name violates naming convention.
As per coding guidelines, test methods should follow the Method_Scenario_Expected pattern. Consider renaming to SiteNavigation_FilesFromUnseenChildTocs_ResolvesCorrectly.
As per coding guidelines: "Test method naming convention: Method_Scenario_Expected."
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/Navigation.Tests/Assembler/SiteNavigationTests.cs` around lines 461 -
462, Rename the test method SiteNavigationResolvesFilesFromUnseenChildTocs to
follow the Method_Scenario_Expected pattern (e.g.,
SiteNavigation_FilesFromUnseenChildTocs_ResolvesCorrectly) and update any
references/usages accordingly; keep the [Fact] attribute and method body
unchanged, just change the method identifier so it complies with the naming
convention.
Pulls in the latest hub-pages work:
- HubLinkValidator and HubUrl helpers
- Site-prefix-aware URL handling for {hero}, {link-card}, {whats-new}
- Hub directive links opt out of body-level hx-boost
- Restored V2 page lookup registration
Conflict resolution:
- config/navigation-v2.yml: keep demo/findability (superset of IA titles
and wired pages; hub-pages held only stale placeholder leaves).
- NavigationViewModel.cs / IsolatedBuildNavigationHtmlWriter.cs: dedupe
the Branding property and trailing-comma re-ordering only.
Why
This PR provides a single demo branch that reconciles the findability work across the navigation, hub-page, and landing-page prototypes. Keeping them together makes it possible to review and test the end-to-end experience before deciding how to split or sequence production rollout.
URL: https://docs-v3-preview.elastic.dev/elastic/docs-builder/docs/3256
What
Branch contributions
nav-v2contributes the new IA prototype, label-section navigation model, accordion sidebar behavior, placeholder page generation, and Nav V2 frontend shell. PR: Prototype nav-v2: new IA with label sections, accordion sidebar #2927.nav-v2-sectionsbuilds onnav-v2with independent sidebar islands, dynamic top-bar sections, API/reference section handling, and related HTMX navigation behavior. PR: Nav sections: independent sidebar islands and dynamic top bar #3133.hub-pagesbuilds onnav-v2-sectionswith product hub page support, hub-specific directives and styling, product hub routing, product metadata presentation, and Elasticsearch/Kibana hub examples. PR: Findability - prototype - Hub pages #3223.landing-page/prototypeadds the search-first documentation landing page prototype, with version disambiguation, popular destinations, getting-started routes, solution browsing, and a product index. PR: [Findability] Landing page prototype #3250.demo/findabilityreconciles those branches into one branch for demo purposes. It does not add a separate product feature beyond combining the stack.Estimated hub-page build time
Local forced isolated HTML builds with
--skip-api --exporters htmlshowednav-v2-sectionsprocessing 230 files in 1.745s, and this demo branch processing 239 files in 1.804s. That is about +59ms for the hub-page layer and related added docs files in this repo.Based on that run, budget the marginal cost of each additional hub page in the low tens of milliseconds during isolated HTML generation, roughly <=30ms per page on this machine. Production assembler builds will be dominated by repository checkout, static assets, API/reference work, cross-link fetching, and upload/indexing overhead, so a small number of hub pages should not materially change total build time.
Production rollout considerations
nav-v2, thennav-v2-sections, thenhub-pages, then the landing-page work, or keep the production branch explicitly stacked until all prerequisites are merged.Made with Cursor