Navigation: level-0 section: entries drive the top nav bar - #3792
Navigation: level-0 section: entries drive the top nav bar#3792theletterf wants to merge 7 commits into
Conversation
|
@florent-leborgne — the dropdown from #3223 is fully supported here, it just moved to a slightly different schema. Here is how to turn Drop this into - title: Products
children:
- title: Stack products # a child WITH children => group heading
children:
- title: Elasticsearch
page: docs-content://products/elasticsearch/v9.md
- title: Kibana
page: docs-content://products/kibana/v9.mdThat renders exactly the panel in your screenshot: a "Stack products" heading with the two links under it. What changed from your prototype
The dropdown label is a pure toggle, not a link. Your version put an So if - title: Products
children:
- title: All products # childless entries render as links with no heading
url: /products/
- title: Stack products
children:
- title: Elasticsearch
page: docs-content://products/elasticsearch/v9.mdChildless children are collected into an unlabelled run at the position you put them, so this puts "All products" above the "Stack products" heading. If a dropdown landing page turns out to be a real requirement, say so and I will look at making the label both toggle and link properly. Things that will fail the build
Not portedThe Two behaviours you get for free
|
d701ff9 to
61c8b5b
Compare
Mpdreamz
left a comment
There was a problem hiding this comment.
dropdown:
Lets not do this now, lets wait for @florent-leborgne hub pages to land in docs-builder and docs-content and then think about how we want to expose this.
external:
can that be external: url, that way we can include API's to bump.sh for now.
…w.yml
Adds a config-level section: grouping to navigation_preview.yml that maps
the 11 flat top-level toc: entries to 5 named tabs in the top nav bar.
Sections are config-only — children are added to the site tree as flat
roots, so no page URLs change.
New ISiteNavigationEntry interface and SiteSectionRef record allow the
YAML converter to parse both toc: and section: entries. SiteTableOfContents
becomes List<ISiteNavigationEntry>. SiteNavigation iterates entries and
descends into section children when encountered.
SectionTopNavBuilder derives TopNavRenderModel from the nav file's entry
list. Section tabs carry SectionIds so active state is resolved by
comparing the current page's NavigationRoot.Id to the tab's set.
BuildContext.TopNav wires the render model through to every page.
_SecondaryNav.cshtml renders the tabs and delegates dropdown/external
behaviour to secondary-nav.ts.
Section structure in navigation_preview.yml:
- section: Guides (get-started, solutions, manage-data, explore-analyze,
deploy-manage, cloud-account)
- section: Troubleshoot (troubleshoot)
- section: Release notes (release-notes/intro + release children)
- section: Reference (reference + reference children)
- section: Extend (extend, contribute-docs)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
01866f5 to
1722e57
Compare
theletterf
left a comment
There was a problem hiding this comment.
Thanks for the review, Martijn!
On dropdown:: Agreed — deferring until hub pages land in docs-content. The implementation already removes the dropdown: surface from this PR. We can add it back in a follow-up once we have a concrete content target.
On external: url syntax: The current external: true + url: split is intentional. Here is why:
external: is a behavioral flag (open in new tab, no active-state tracking). url: is the destination. Keeping them separate gives us:
- Consistency with internal sections: Internal sections can also carry a
url:override (tab points at a specific page instead of the first child's index). A singleexternal: <url>key would make external and internal sections use different mechanisms for the same concept. - Validation surface: With two keys, the YAML validator can catch
external: truewithouturl:(ambiguous) orurl:withoutexternal: true(assumed internal) independently. Withexternal: <url>, the value of the key carries dual meaning — both "is external" and "what URL" — and the code must distinguishexternal: truefromexternal: https://.... - Extensibility: If we later need
rel: nofollowortarget: _blankoptions, they sit naturally alongsideexternal: true. Withexternal: url, those attributes have no obvious home.
That said, if you feel strongly about the syntax change I can implement external: <url> — it would be a small change to the YAML converter. Let me know.
Separately: the conflicts with main (navigation_preview.yml feature-flag mechanism, Island = false on SiteTableOfContentsRef, new CheckoutsFileSystem in AssemblerBuildService) are now resolved. The branch is rebased cleanly on top of the commits you merged this week.
…row icon
Replace two-key syntax (external: true + url:) with single-key:
- section: APIs
external: https://...
SiteSectionRef now carries ExternalUrl (string?) with IsExternal computed.
_SecondaryNav.cshtml drops the SVG arrow from external link tabs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
External sections now use external: <url> directly, no separate url: key needed. The arrow icon is also removed from external tabs.
- section: APIs
external: https://www.elastic.co/docs/api/SiteSectionRef carries ExternalUrl (string?) with IsExternal computed from it.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…hetics The sidebar dropdown (isUsingNavigationDropdown) is suppressed when section tabs are active. Navigate to Reference via #secondary-nav instead. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Links to https://www.elastic.co/docs/api/ using the external: <url> syntax. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…oot, Release notes, Extend Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@copilot Push an empty commit to retrigger CI. |
Done — pushed to retrigger CI. |

Summary
Adds configurable top-nav driven by
section:entries inconfig/navigation_preview.yml.The 11 flat
toc:entries are grouped into 5 named tabs without moving any pages.Design: config-level grouping
section:entries are YAML-only — they are not tree nodes. Theirtoc:children are addedto
SiteNavigation.TopLevelItemsas flat roots, exactly as before. Active state is resolvedby matching the current page's
NavigationRoot.Idagainst the section's set of child IDs.No page URLs change.
FileNavigationLeaf.DetermineUrlderives URLs from each entry's ownpath_prefix, which is positional-independent. URL invariance is the primary correctness gate.Config surface (
navigation_preview.yml)Two entry shapes are supported:
dropdown:is deferred until hub pages land in docs-content.What stays unchanged
LlmsNavigationEnhancerand sitemap logicnavigation.yml(flat, for non-preview builds)What's new
config/navigation_preview.ymlsection:groups replace 11 flat entriesSiteNavigationFile.csISiteNavigationEntry,SiteSectionRef, updated YAML convertersSiteNavigation.csISiteNavigationEntry, descends into section childrenSectionTopNavBuilder.csTopNavRenderModelfrom nav file entriesBuildContext.csTopNavproperty wires render model to every page_SecondaryNav.cshtmlAssembleSources.csReadBlockdescends into section childrenNot in scope (deferred)
dropdown:sections — waiting for hub pages to land in docs-contentTest plan
dotnet buildpasses (0 errors)dotnet test tests/Elastic.Documentation.Configuration.Testspasses (673 tests)dotnet test tests/Navigation.Testspasses (216 tests)npm testforsecondary-nav.test.ts🤖 Generated with Claude Code