Skip to content

Demo findability prototypes together#3256

Open
theletterf wants to merge 156 commits intomainfrom
demo/findability
Open

Demo findability prototypes together#3256
theletterf wants to merge 156 commits intomainfrom
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>
itsalexcm and others added 20 commits May 4, 2026 16:14
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
- Remove the INodeNavigationItem<IDocumentationFile,INavigationItem> case
  from ResolvePageCrossLinksRecursive — it is always caught by the
  INodeNavigationItem<INavigationModel,INavigationItem> case above it
- Discard TryAdd bool returns with _ = to satisfy IDE0058

Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 (1M context) <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>
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>
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.
Replaces the previous hero/card layout with a search-first design:
- Version disambiguation banner with link to 8.x docs
- Prominent search bar with What's new ribbon
- Analytics-driven popular destinations grid
- Get started cards (local, cloud trial, fundamentals)
- Browse by solution (Search, Observability, Security) with sub-links
- Full product index categorized by stack, cloud, ingest, query languages, APM agents, and developer tools
- Scoped CSS replacing Tailwind utility classes

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@theletterf theletterf requested review from a team as code owners May 6, 2026 08:54
@theletterf theletterf added the redesign enable redesign feature flag label May 6, 2026
@theletterf theletterf requested a review from reakaleek May 6, 2026 08:54
Prevent the landing page prototype from leaking reset and link styles into the shared Elastic navigation chrome.

Co-authored-by: OpenAI GPT-5.5 <noreply@openai.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
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.

10 participants