Follow-up to #9 (merged as cdafc34). Two related regressions in the API-reference docs were deferred from that PR's review because the clean fix is a single design change rather than a patch.
Problem
1. The /docs layout loader ships the full API symbols JSON in every page's SSR payload.
website/src/routes/docs.tsx returns apiData (the whole ~250KB api-data/symbols.gen.json) from its loader. The dynamic import() keeps it out of the client JS bundle, but returning it from the loader serializes it into the dehydration payload of every /docs/* page — including pure-content pages like /docs/getting-started that render no API tables. This defeats the lazy-loading goal: pre-#9, the layout shipped only {name, kind} nav entries and symbol pages fetched a single symbol server-side.
2. API symbol pages lost head() and notFound() semantics.
website/src/routes/docs/api/$symbol.tsx:
- No
head() — every API page inherits the generic site title and has no per-symbol <title>/meta description (SEO + tab-title regression vs. main).
- The loader never throws
notFound(), so /docs/api/DoesNotExist SSRs with HTTP 200, the declared notFoundComponent is dead code, and it's byte-duplicated by an inline "Symbol not found" fallback in the component body.
Recommended approach (option C from the #9 discussion)
Split the build-time output into per-symbol chunks instead of one monolith:
Also in scope (same area, smaller)
Verification
🤖 Generated with Claude Code
Follow-up to #9 (merged as cdafc34). Two related regressions in the API-reference docs were deferred from that PR's review because the clean fix is a single design change rather than a patch.
Problem
1. The
/docslayout loader ships the full API symbols JSON in every page's SSR payload.website/src/routes/docs.tsxreturnsapiData(the whole ~250KBapi-data/symbols.gen.json) from its loader. The dynamicimport()keeps it out of the client JS bundle, but returning it from the loader serializes it into the dehydration payload of every/docs/*page — including pure-content pages like/docs/getting-startedthat render no API tables. This defeats the lazy-loading goal: pre-#9, the layout shipped only{name, kind}nav entries and symbol pages fetched a single symbol server-side.2. API symbol pages lost
head()andnotFound()semantics.website/src/routes/docs/api/$symbol.tsx:head()— every API page inherits the generic site title and has no per-symbol<title>/meta description (SEO + tab-title regression vs. main).notFound(), so/docs/api/DoesNotExistSSRs with HTTP 200, the declarednotFoundComponentis dead code, and it's byte-duplicated by an inline "Symbol not found" fallback in the component body.Recommended approach (option C from the #9 discussion)
Split the build-time output into per-symbol chunks instead of one monolith:
website/scripts/extract-api.tsemitsapi-data/<symbol>.gen.jsonper symbol, plus a smallapi-data/index.gen.json(name → kind) for nav + link detection.docs.tsxloader returns only the small index (dropapiDatafrom loader data).docs/api/$symbol.tsxloader imports the single<symbol>.gen.json, throwsnotFound()when missing (server fn or loader), and setshead()title/description from it. Delete the inline fallback — letnotFoundComponenthandle it.TypeLinktooltips dynamic-import the hovered symbol's chunk on demand instead of reading a page-wideapiData.*/api-data/symbols.gen.jsonto*/api-data/*.gen.jsonso all chunks resolve without being checked in (they stay gitignored + generated, same as today).Also in scope (same area, smaller)
$slug.tsxin docs: precompile Markdoc into React route components at build time #9 removed the docs-layoutnotFoundComponent, so unknown/docs/<slug>URLs now hit TanStack Router's bare default not-found instead of the styled page. Add anotFoundComponenttodocs.tsx(or a rootdefaultNotFoundComponent).Verification
/docs/getting-startedSSR HTML no longer contains the symbols payload (was ~250KB)./docs/api/<Known>has the correct<title>and meta description;/docs/api/<Bogus>returns 404 and renders the branded not-found.vp run readypasses with the file absent (ambient declaration covers the per-symbol chunks).🤖 Generated with Claude Code