SoftNav page TOC and hide-page nav entries
Summary
Hubs that use SoftNavunchecked with Default UI or Valentus can soft-swap mast, left nav, and article without a full reload.
The right-rail page TOC (aside.toc.sidebar) is built once by bundled site.js from article.doc headings.
After a soft navigation (for example from a changelog index to an changelog-details orphan page), the article updates but the TOC still lists the previous page’s sections.
This proposal separates two concerns:
-
Near-term (UI bolt-on): rebuild the page TOC when the article region changes — interim extension
@antora-supplemental/soft-nav-page-tocunchecked, wired intofacto-stackunchecked hub profiles. -
Medium-term (Antora core / nav model): first-class hide-page entries — routable, xref-able, and searchable, but omitted from the published left nav tree unless explicitly promoted.
Author directive naming
Single author flag: :hide-page: — this page is hidden from the left nav tree only (omitted from nav.adoc); it remains published (URL, xref, search). Not unpublished, not noindex, not access control.
Parent link: :navtree-parent: parent-page.adoc — which nav tree parent should breadcrumbs and contextual left-nav injection use (required when path heuristics such as *-details/ do not apply).
- Build-time associations (cross-tree links to hidden subpages):
navtree-registry.jsonbeside the component and/or ` -
navtree-parent-association:` comment lines in
nav.adoc(not rendered; parsed at compose time). Page-level:navtree-parent:wins over registry rules.
Do not use for this: :omit-nav:, :nav-hidden: — ambiguous. :orphan: — overloaded with Antora diagnostics.
Migration only (still parsed, not documented for new pages): :hide-from-navtree:, :page-nav-hidden:, :page-nav-parent:.
Composed HTML meta: antora-supplemental:hide-page, optional antora-supplemental:navtree-parent.
Problem (right-rail TOC)
| Layer | Behavior today |
|---|---|
SoftNav |
Registers |
Default UI |
On initial load, scans heading IDs under |
Gap |
Fetched HTML for the target page is never re-run through |
Not the same bug: orphan pages (omitted from nav.adoc) explain weak left-nav “current page” highlighting on detail URLs; they do not by themselves prevent TOC refresh. Fixing the rail requires rebuild-or-swap after article swap regardless of nav tree membership.
Interim extension (shippable now)
Package: soft-nav-page-tocunchecked
-
Publishes
_/js/soft-nav-page-toc.jsviasiteCatalog.addFile. -
Optionally injects a defer script immediately after
ui/js/site.json each composed page. -
Listens for
soft-nav:loaded/doc-nav:loadedand rebuilds the aside TOC using the same heading selectors Default UI uses (sectN,:not(.discrete),:toclevelsfromdata-levelson the aside).
Requirements for sites:
-
SoftNav loaded from supplemental UI (before consumers that rebind on
soft-nav:loaded). -
Default UI / Valentus layout with
aside.toc.sidebarandarticle.doc.
Upstream ask A — page TOC lifecycle in Default UI
Target: antora-ui-defaultunchecked (and Valentus parity).
-
Export a supported
buildPageToc(document)(name negotiable) that rebuilds aside + embedded TOC and rebinds scroll-spy. -
Document a single navigation event contract (
doc-nav:loadedor native equivalent) that fire-and-forget UI scripts can subscribe to after any in-place article swap — not only SoftNav. -
Optional: register
aside.tocas a fourth SoftNav region in chassis docs so fetch-and-replace works without rescanning (rebuild is still the minimal fix).
Upstream ask B — hide-page routable entries
Antora today has no first-class “listed in the site model but hidden from the left nav tree” entry type.
Common author patterns:
-
Orphans — pages under
pages/reachable by URL, xref, and search; omitted fromnav.adoc(changelog-details, legal footnotes, print-only explainer pages). -
Promoted later — same page later added to nav when the story graduates from appendix to first-class doc.
Authors want:
-
Stable URLs and xrefs without expanding the left nav forest (UX and HTML payload on every page share the same baked nav tree).
-
Optional breadcrumb or contextual TOC injection for hidden targets without duplicating 20+ nav lines.
Interim author convention (nav-drift + SoftNav): declare :hide-page: and optional :navtree-parent: changelog.adoc on pages intentionally omitted from nav.adoc. With nav-drift --require-in-nav, marked pages report as nav-hidden-page (intentional), not page-missing-from-nav. SoftNav and @antora-supplemental/soft-nav-page-toc inject parent breadcrumbs, a single nav-tree child under the parent, and matching <meta> tags at build time.
Possible upstream directions (for discussion, not a finished API):
-
Promote
:hide-page:in Antora core so generators and UI bundles understand intentional nav-tree omission without CLI scanning. -
Nav file attribute on xref lines, for example
xref:path.adoc[Label, hide-page](illustrative syntax only). -
Optional
navtree-parent-associationmetadata in nav files or component registry for parent links when URL structure alone is insufficient. -
Playbook key, for example
site.nav.hidden_pageswith explicit allow-list for sitemap/search. -
Generator output: omit hidden pages from
nav-data.js/ menu partial but retain them in the content catalog and page manifest.
Performance note: hiding entries reduces left-rail markup size; it does not remove the need to generate detail HTML. A richer optimization (lazy nav subtrees) is out of scope for v1 but pairs naturally with hide-page metadata.
Shipped client behavior (chassis / hub soft-nav.js):
-
Default
SoftNav.swapNav = false— left nav tree is not replaced on soft loads; mast + article update in place. -
SoftNav.rebuildPageToc()runs after every soft navigation (and initial load). -
SoftNav.scrollToTop = true— cross-page soft nav scrolls the window to the top unless the destination URL has a#hash. -
Hide-page entries inject a parent breadcrumb (
… / Changelog / Detail title) and a single child under the parent nav link on hard and soft loads (:hide-page:+:navtree-parent:).
Upstream ask C — paginated long indices (changelog, release notes)
Long index pages (changelog timelines, exhaustive reference lists) will overwhelm initial HTML download and render cost. Pagination should be on by default for tagged index pages (for example :page-pagination: changelog or :page-tags: paginated-index), with :page-pagination: none to opt out on pages that must stay one URL.
Open design questions (future extension or Antora core):
-
Precalculation — chunk boundaries must be known at publish time (heading-level splits, byte/line budgets, or explicit
===page breaks) so the first response stays small before the reader opts into page 2+. -
URLs — bare URL resolves to page 1; suffix or query distinguishes later pages (for example
/changelog/+/changelog/2/or?page=2). SoftNav and canonical links must agree. -
SoftNav — paginated index segments may soft-load inside the article column while nav + TOC stay stable; TOC might list only the current segment or link sibling pages.
-
Nav tree — do not mirror every changelog day in
nav.adoc; keep hide-page details + pagination in the index body.
Non-goals
-
Changing Valentus TOC truncate/fade CSS to mask long labels — serial changelog pages should use heading structure instead.
-
Replacing SoftNav with full SPA routing — Antora remains static-first.
Suggested Zulip post
Post in Antora Zulip → community / generalunchecked (or UI stream if you prefer):
SoftNav + Default UI: the aside page TOC goes stale after in-component soft navigation because
site.jsonly builds it on full load. We documented a proposal (hide-page nav entries + TOC rebuild lifecycle) here:Interim bolt-on: https://github.com/antora-supplemental/soft-nav-page-tocunchecked — feedback welcome on whether Default UI should export
buildPageToc()and standardizedoc-nav:loaded.
References
-
nav-driftunchecked —
--require-in-navaudits -
D Lang Supplemental docs hubunchecked — changelog-details pattern