Skip to content

Experimental shared chrome build mode (client-side chrome restoration) #2659

Description

@chalin

Add an opt-in, experimental chrome build modetd.chrome = full | shared (default full) — that emits the repeated page chrome (navbar, footer, left side-nav) on one donor page per locale instead of on every page, and restores it in the browser on the others. It's off by default (full), so production builds are byte-for-byte unchanged.

A shared build is functionally equivalent to a full one: a small shipped script — client-side chrome restoration (CCR) — re-injects each region and re-derives its per-page state, so one build serves both readers (complete pages once JS runs) and link checkers (each shared link emitted once in the static HTML). That makes shared a good fit for the builds whole-site tooling consumes — local dev, deploy previews, link-checking, and output diffing — while full stays the default for production.

Why, experimental status, prototype notes, and the lean-render → shared naming change

Why

A docs site re-emits the same auto-generated chrome on every page. That repetition inflates the build, the output, and anything that processes every page — most visibly a link checker, which re-parses the same chrome links on every page. On a large site that's millions of redundant link occurrences.

Where this sits relative to existing tooling — checkers already dedup URLs; almost none dedup the rendered markup:

  • URL/result dedup + caching (htmltest, html-proofer, Lychee, muffet, linkchecker, wget --spider) avoids re-fetching a seen URL, but still parses the chrome markup on every page.
  • Generator-integrated checkers (Sphinx linkcheck, Docusaurus onBrokenLinks, MkDocs --strict, mdbook-linkcheck) dedup by construction but are internal-link-only.

shared mode is the missing third option: build-time markup removal, checker-agnostic (htmltest, Lychee, anything that reads HTML), covering external links too — and it can retire post-build "normalize/dedup" passes. Because CCR restores the chrome client-side, the same lean build is also usable for dev and previews, not only as a throwaway checker artifact. It's an MPA take on the app-shell pattern: one instance of each region, restored on the client.

Experimental

full stays the default and production output is unchanged, but the region semantics and the set of restored per-page hints may still evolve, with no stability guarantees yet. Feedback on the approach and scope is welcome.

Naming note (2026-06): originally proposed as lean render (td.lean_render); now framed as the shared chrome build mode (td.chrome) with client-side chrome restoration (CCR) as the mechanism — the earlier name collided with framework per-component "CSR" / client-side rendering. #2660 / #2661 and older comments use the original terms.

Notes (prototype → implementation)

On a large multilingual site the shared build was ~15% faster and cut link-occurrence count ~7.7× (≈2.0M → 0.26M), roughly 7–10× faster internal link checking. A hermetic jsdom fixture suite plus a whole-site equivalence scoreboard over docsy.dev confirm a client-restored shared build matches a full build (0 differing pages).

Tasks

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions