Skip to content

feat: render the docs sidebar once per section, version, and language (render-once E)#2039

Merged
markdumay merged 1 commit into
mainfrom
feat/render-once-e-sidebar-cache
Jul 16, 2026
Merged

feat: render the docs sidebar once per section, version, and language (render-once E)#2039
markdumay merged 1 commit into
mainfrom
feat/render-once-e-sidebar-cache

Conversation

@markdumay

Copy link
Copy Markdown
Collaborator

Render-once program — chunk E (HELD for maintainer review)

Part of the Hinode render-once implementation program (design:
gethinode.com docs/superpowers/specs/2026-07-15-sidebar-render-once-design.md, maintainer
decisions §7-1..5). Reduces ~3,420 sidebar item renders to ~114 (one tree per
section/version/language/variant, ~30×) on the exampleSite docs.

Changes

  • New page/sidebar-cached.html — uncached wrapper: key tuple (section, version, lang,
    variant), context canonicalized to the (versioned) section root, baseURL via
    partialCached utilities/GetBaseURL.html site (mod-utils v6.6.0), filename as explicit
    arg; Mode B (level-min ≥ 2) stays uncached (§7-3). Raw assets/sidebar.html remains
    cache-free and override-friendly (§7-5). Both call sites switched.
  • assets/sidebar.html page-independent — no server active, canonical collapsed state,
    current-group anchor swap removed (titles always link), data-sidebar-nav root hook,
    data-sidebar-match="prefix", zero Scratch reads inside the cached subtree, internal icons
    render mode="svg" (mod-fontawesome v6.1.0 per-call arg, §7-4 — no sprite-registration
    hazard); titleCase exact now reads the section root (§7-1, documented behavior change).
  • New critical JS sidebar-active.js — per-instance highlight (offcanvas + desktop),
    aria-current (a11y improvement), collapse-trail expansion, current-group click intercept
    (§7-2), no-transition init. Plus js-detect.js (no-jsjs) and a .no-js SCSS fallback
    (all groups expanded without JS — strictly better than before). No inline styles/scripts (CSP).
  • go.mod — mod-utils v6.5.1→v6.6.0, mod-fontawesome v6.0.2→v6.1.0 (drags the FA webfonts
    snapshot: 4 woff2 files, byte-verified upstream). hugo mod tidy pruned exampleSite pins
    (same pruning the daily mod-update applies).

Gate evidence (deliberate-diff slice; own gate per design §1.5)

  1. Within-key identity: all 60 docs sidebars byte-identical inside one key — independently
    re-verified by the driver: 1 distinct nav hash across 120 instances, 0 server active.
  2. Cached output byte-identical to the uncached intermediate (allowlist excepted).
  3. Double-build determinism PASS (allowlist only); 0 ERROR; 98/26/24 pages; WARN set unchanged.
  4. Candidate-vs-stock classified per line (132 diff lines): nav attrs / aria-expanded /
    collapse-show / active-removal / anchor-swap / bundle+CSS hashes / woff2 — zero unclassified.
  5. Functional check (Chromium): highlight + trail on both copies, current-group click folds
    without navigating, js class swap, .no-js rule in compiled CSS.
  6. pnpm test green (incl. eslint on the new JS).

Notes for review

  • Unlisted-subpage edge case in hand-written Mode C menus loses group pre-expansion (approved
    §2.2 contract).
  • Mode A/B parity is code-level; the exampleSite exercises Mode C only.

🤖 Generated with Claude Code

@netlify

netlify Bot commented Jul 16, 2026

Copy link
Copy Markdown

Deploy Preview for gethinode-demo ready!

Name Link
🔨 Latest commit 87c7564
🔍 Latest deploy log https://app.netlify.com/projects/gethinode-demo/deploys/6a590730e1e0e70008c5f816
😎 Deploy Preview https://deploy-preview-2039--gethinode-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

The sidebar tree is now rendered once per (section, version, language, variant) via
partialCached in the new uncached wrapper page/sidebar-cached.html, used by both call
sites (page/sidebar.html and docs/all.html). The wrapper canonicalizes the page context
to the (versioned) section root, passes the base URL (mod-utils GetBaseURL) and the
error-path filename as explicit arguments, and leaves Mode B (level-min >= 2) uncached.

The renderer (assets/sidebar.html) no longer reads per-page state: the server stops
emitting the active class and the expanded collapse trail, always renders the canonical
collapsed state, and the current-group anchor swap is removed (the group title always
renders its link). Sidebar-internal icons render as inline SVG through the per-call
mode argument of mod-fontawesome v6.1.0, including the external-link cue threaded
through the new icon-mode argument of assets/link.html, so no per-page sprite
registration happens inside the cached subtree.

Active-item highlighting, the expanded trail (aria-current, aria-expanded), and the
current-group toggle UX move to the new critical script sidebar-active.js, applied per
sidebar instance before first paint. Without JavaScript every sidebar group renders
expanded via a no-js fallback rule; critical/js-detect.js swaps the marker class.

Requires mod-fontawesome v6.1.0 and mod-utils v6.6.0; the FontAwesome webfonts
snapshot bump (upstream 2026-07-15) rides along with the module update.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@markdumay
markdumay force-pushed the feat/render-once-e-sidebar-cache branch from f5e0c22 to 87c7564 Compare July 16, 2026 16:30
@markdumay

Copy link
Copy Markdown
Collaborator Author

Rebased onto post-flip main (#2042 merged). Conflict resolutions: sidebar-internal icons keep E's mode="svg" (cache-safe inline SVG — page-based sprite registration would land on the canonical section-root only); link.html combines D8a's page threading with E's opt-in iconMode; mod-fontawesome stays at main's v6.1.1. Full gate re-verified on the deterministic base: two builds FULLY byte-identical (no allowlist), determinism script PASS, 1 sidebar tree across 120 nav instances, 0 server-emitted active, WARN parity, lint green. The 4 dangling sprite refs in the audit are the pre-existing mod-blocks deferred-indirect residual (#2042's runbook steps 2-4), unrelated to this PR.

@markdumay
markdumay enabled auto-merge July 16, 2026 16:34
@markdumay
markdumay merged commit 1408966 into main Jul 16, 2026
16 checks passed
@markdumay

Copy link
Copy Markdown
Collaborator Author

🎉 This PR is included in version 3.4.0 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@markdumay
markdumay deleted the feat/render-once-e-sidebar-cache branch July 16, 2026 17:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant