Skip to content

ui(docs): source the docs TOC from the compiled MDX toc instead of scraping the rendered DOM #9872

Description

@JSONbored

Follow-up from #9588, which fixed 26 of the 27 react-hooks 7 sites. This is the last one.

Problem

DocsToc (apps/loopover-ui/src/components/site/docs-toc.tsx) builds the "On this page" rail by querying the rendered DOM for h2, h3 inside article.prose-docs, assigning ids to any heading that lacks one, and reading the result into state from an effect.

That is the one remaining react-hooks/set-state-in-effect site in the app, and it is the reason the rule is still at warn rather than error. It is also fragile independently of lint: the TOC depends on the rendered markup rather than on the content, so a styling change to the article wrapper silently empties the rail.

The real fix

fumadocs compiles a TOC already — CompiledMDXProperties.toc: TOCItemType[] (node_modules/fumadocs-mdx/dist/core-BmvJhZxm.d.ts). Sourcing the rail from that removes the DOM scrape, the id back-filling, and the effect together.

Why it is not a one-liner

Two things have to be resolved first:

  1. The data and the component are in different routes. DocsToc renders in the docs LAYOUT (src/routes/docs.tsx), while the compiled page — and therefore its toc — is resolved in the child route (src/routes/docs.$slug.tsx). The toc has to reach the layout, via route context or by moving the rail into the child.
  2. Not every docs page is MDX. docs.index.tsx and docs.fumadocs-spike-api-reference.tsx render under the same layout and have no compiled toc. They get a rail today from the DOM scrape, so a naive switch silently removes it for them.

Acceptance

The rail is built from content rather than from rendered markup for MDX pages, non-MDX docs pages keep a working rail (or deliberately opt out), and react-hooks/set-state-in-effect goes back to error in apps/loopover-ui/eslint.config.ts with no remaining suppressions.

Metadata

Metadata

Assignees

Labels

maintainer-onlyOwner-only work — yields no Gittensor points.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions