Skip to content

Demo findability prototypes together#3256

Open
theletterf wants to merge 198 commits into
mainfrom
demo/findability
Open

Demo findability prototypes together#3256
theletterf wants to merge 198 commits into
mainfrom
demo/findability

Conversation

@theletterf
Copy link
Copy Markdown
Member

@theletterf theletterf commented May 6, 2026

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

Estimated hub-page build time

Local forced isolated HTML builds with --skip-api --exporters html showed nav-v2-sections processing 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

  • Merge order matters: land nav-v2, then nav-v2-sections, then hub-pages, then the landing-page work, or keep the production branch explicitly stacked until all prerequisites are merged.
  • Keep the Nav V2 and hub-page behavior gated by configuration or feature flags until the demo has passed design, content, accessibility, and navigation regression testing.
  • Before production, scope the landing-page CSS so resets and generic selectors do not affect the shared header, footer, or embedded React search components.
  • Verify all hub-page URLs, generated placeholder pages, product metadata links, and HTMX swaps in assembler previews, not only isolated docs builds.
  • Revisit build monitoring after adding real product hubs at scale. The current estimate is for the small demo set, and larger hub rollouts should be checked against CI timing and assembler preview timing.

Made with Cursor

theletterf and others added 30 commits March 20, 2026 09:37
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
itsalexcm and others added 5 commits May 8, 2026 12:45
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>
KOTungseth and others added 2 commits May 8, 2026 17:39
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>
@alaudazzi
Copy link
Copy Markdown
Member

@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?

@theletterf
Copy link
Copy Markdown
Member Author

@alaudazzi If you mean the landing / home, that's a question for @KOTungseth and @itsalexcm

florent-leborgne and others added 10 commits May 11, 2026 17:55
# 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.
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

♻️ Duplicate comments (1)
src/Elastic.Markdown/Layout/_LandingPage.cshtml (1)

39-320: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Scope 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-page consistently (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

📥 Commits

Reviewing files that changed from the base of the PR and between af3da7b and 02a0979.

📒 Files selected for processing (30)
  • config/assembler.yml
  • config/navigation-v2.yml
  • docs/_docset.yml
  • src/Elastic.Documentation.Configuration/Elastic.Documentation.Configuration.csproj
  • src/Elastic.Documentation.Configuration/Toc/NavigationV2File.cs
  • src/Elastic.Documentation.Links/CrossLinks/CrossLinkFetcher.cs
  • src/Elastic.Documentation.Navigation/V2/NavigationSection.cs
  • src/Elastic.Documentation.Navigation/V2/SectionNavigationNode.cs
  • src/Elastic.Documentation.Navigation/V2/SiteNavigationV2.cs
  • src/Elastic.Documentation.Site/Assets/pages-nav-v2.ts
  • src/Elastic.Documentation.Site/Assets/secondary-nav-dropdown.css
  • src/Elastic.Documentation.Site/Assets/styles.css
  • src/Elastic.Documentation.Site/Layout/_SecondaryNav.cshtml
  • 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
  • src/Elastic.Documentation.Site/_ViewModels.cs
  • src/Elastic.Documentation.Site/synthetics/journeys/navigation-test.journey.ts
  • src/Elastic.Markdown/HtmlWriter.cs
  • src/Elastic.Markdown/IO/MarkdownFile.cs
  • src/Elastic.Markdown/Layout/_LandingPage.cshtml
  • src/Elastic.Markdown/Layout/_TableOfContents.cshtml
  • src/Elastic.Markdown/Myst/Directives/DirectiveBlockParser.cs
  • src/Elastic.Markdown/Myst/Directives/DirectiveHtmlRenderer.cs
  • src/Elastic.Markdown/Page/Index.cshtml
  • src/Elastic.Markdown/Page/IndexViewModel.cs
  • src/services/Elastic.Documentation.Assembler/Building/AssemblerBuildService.cs
  • src/services/Elastic.Documentation.Assembler/Navigation/GlobalNavigationHtmlWriter.cs
  • tests/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

Comment on lines +23 to +31
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>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

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">
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

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.

Comment on lines +310 to +311
[Fact]
public void SiteNavigationV2PageEntriesResolveFilesFromUnseenChildTocs()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

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.

Comment on lines +385 to +386
[Fact]
public void SiteNavigationV2PageEntriesUseV2OrderForPrevNext()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

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.

Comment on lines +461 to +462
[Fact]
public void SiteNavigationResolvesFilesFromUnseenChildTocs()
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

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.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

redesign enable redesign feature flag

Projects

None yet

Development

Successfully merging this pull request may close these issues.