Skip to content

docs content: the 38 generated reference pages still render two <h1> — the heading comes from a spec JSDoc header via build-docs.ts #12249

Description

@os-zhuang

One-liner

38 generated pages under content/docs/references/** still render two <h1>. The heading is not in the MDX — it comes from a JSDoc file header in packages/spec/src/**, copied verbatim into the page by packages/spec/scripts/build-docs.ts. #12236 could not fix them and carved the tree out of its new gate.

Measured on origin/main at 20b0fdb

pages under content/docs/** with a body-level `# ` heading 195
of which generated (carry the AUTO-GENERATED marker) 38
body `# ` headings inside those 38 pages 43 (41 distinct texts)

Two examples, and where the text really lives:

content/docs/references/data/context-tokens.mdx:11 # Why this lives in `spec`
<- packages/spec/src/data/context-tokens.zod.ts:10 * # Why this lives in `spec`
content/docs/references/kernel/*.mdx # <Name> Protocol
<- the same JSDoc file header, rendered by renderFileDescription()

build-docs.ts line ~422 inserts fileDesc into the page with no heading-level
normalisation:

if (fileDesc) {
md += `${fileDesc}\n\n`;
}

Why #12236 could not do it

  1. Hand-editing the 38 MDX files is reverted by the next generator run, and check:docs (pnpm --filter @objectstack/spec check:docs, a required step in Lint & Repo Gates) regenerates the tree and fails on any difference — so the hand-fix would have shipped CI-red.
  2. The real fix is in packages/**, which epic epic(docs-site): the site is technically un-indexable — fix robots/sitemap/canonical/OG first, then the keyword shape #12243 declares out of territory.

Options

  • A — normalise in the generator. Demote every ATX heading in fileDesc by one level at emit time in build-docs.ts. One place, fixes all 38 and every future one, regenerates 38 tracked files. Note ## TypeScript Usage is already emitted at level 2, so a plain ### demotion lands the file-description headings as its siblings, which is the right level for them.
  • B — fix the JSDoc sources. 41 headings across packages/spec/src/**. Same output, distributed edit, nothing stops the next one.

A is the contract-first shape: the generator owns the page's heading levels, so the level rule belongs where the page is emitted, not in every comment that feeds it.

Acceptance

  • no page under content/docs/references/** contains a body-level # heading
  • pnpm --filter @objectstack/spec check:docs is green with the regenerated tree committed
  • the content/docs/references/** carve-out is deleted from scripts/check-docs-single-h1.mjs — that gate FAILS when an excluded tree becomes clean, so this is mechanical, not a thing to remember

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions