Generate the SDK landing page section lists from sidebars.js - #5179
Conversation
Markers are opt-in, so a green check with low coverage reads as no drift when it means no coverage. Warn (not fail) about section index pages that still hand-maintain a link list, so the gap is visible and new pages get noticed.
The eight SDK landing pages restate the sidebar by hand, so adding a page wires it into sidebars.js and leaves the landing page behind. #5118 is the current example: it added Serverless Workers pages across seven SDKs, and six of the seven landing pages never mentioned the feature. Wraps each `## [Section](url)` list in markers and fills it from the same sidebar Docusaurus builds the left nav from. This run adds 11 missing links, including Serverless Workers to all six SDKs that were missing it. Insert-only on purpose. The sidebar decides which pages appear; existing lines keep their text and their position, and a line the sidebar doesn't know about is preserved rather than deleted. Generating labels from the sidebar would have rewritten 37 of them, several against the sentence-case rule in readme/STYLE.md, and would have deleted the external links inside the Integrations sections. The diff here is 125 insertions and no deletions. Markers are MDX expression comments, so scripts/mdx-to-md.mjs already strips them while the bullets survive as ordinary Markdown. That is why this generates text in place instead of rendering a component: DocCardList is registered as strip-block, and an unwired GuidesGrid already leaves build/guides.md at 225 bytes with no links. Sections whose heading is not a sidebar category — Install and get started, technical resources, community — carry no markers, so their 58 external links stay hand-written.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
| - [Converters and encryption](/develop/dotnet/best-practices/data-handling) | ||
| {/* SIDEBAR-LIST-END */} | ||
|
|
||
| ## Temporal .NET technical resources |
There was a problem hiding this comment.
📝 [vale] reported by reviewdog 🐶
[Temporal.Headings] 'Temporal .NET technical resources' should use sentence-style capitalization.
|
Correcting a number in the description above. It originally cited "65% of landing-page commits touch exactly one page while 1.3% touch all eight." I re-measured that myself and it was wrong: So 44%, not 65%, over a larger commit set than the original figure used (117 vs 79 — the two passes used different windows). Description updated to the verified numbers. The conclusion is unchanged and does not depend on the exact figure: parallel edits across all eight landing pages are rare, single-SDK edits are the norm, and that is the pattern this PR removes the need for. The primary evidence remains #5118 — a feature documented across seven SDKs that six of seven landing pages never mentioned. |
There was a problem hiding this comment.
Pull request overview
Generates SDK landing-page link lists from sidebar data to prevent navigation drift.
Changes:
- Adds sidebar-list generation and validation commands with tests.
- Marks generated regions across eight SDK landing pages.
- Adds 11 missing links, including Serverless Workers links.
Reviewed changes
Copilot reviewed 10 out of 12 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
package.json |
Adds generation and check commands. |
bin/generate-sidebar-link-lists.js |
Implements sidebar-list reconciliation. |
bin/generate-sidebar-link-lists.test.js |
Tests generation behavior and sidebar resolution. |
docs/develop/go/index.mdx |
Marks generated SDK section lists. |
docs/develop/java/index.mdx |
Marks lists and adds missing links. |
docs/develop/dotnet/index.mdx |
Marks lists and adds missing links. |
docs/develop/php/index.mdx |
Marks generated SDK section lists. |
docs/develop/python/index.mdx |
Marks lists and adds missing links. |
docs/develop/python/workers/index.mdx |
Marks the list and adds Serverless Workers. |
docs/develop/ruby/index.mdx |
Marks lists and adds Serverless Workers. |
docs/develop/rust/index.mdx |
Marks lists and adds Serverless Workers. |
docs/develop/typescript/index.mdx |
Marks lists and adds missing links. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| {/* SIDEBAR-LIST-START */} | ||
| - [Worker processes](/develop/python/workers/run-worker-process) | ||
| - [Interceptors](/develop/python/workers/interceptors) | ||
| - [Serverless Workers](/develop/python/workers/serverless-workers) |
- The preserved count used existing.length - sidebarUrls.size, which went negative whenever the sidebar had more entries than the page listed. - Blank lines inside a marked region were dropped, so "insert-only" was quietly destructive on a region with deliberate spacing. - A label-form section= silently resolved to whichever same-named category came first in traversal order. "Quickstart" appears under several sections, so this now refuses and points at the URL form. - Coverage reporting skipped pages with fewer than two links, which hid 10 pages including four workers/index.mdx — the pages most likely to be missing an entry, since a one-link list is thinner than a ten-link one. - The not-found error said "no category labelled" even when the marker had supplied a URL. Also adds five processFile tests. That function had none, so marker parsing, the unmatched-END and unresolvable-page errors, and the promise that content outside the markers never changes were all unverified.
This PR marked docs/develop/python/workers/index.mdx but left the same gap on the other five, so it claimed section index pages were out of scope while including one of them. All six now carry the link, which makes the scope coherent: the Serverless Workers gap is closed at both the landing page and the section index level. The other 46 section index pages remain the separate sweep.
|
Responses to the two review comments. @copilot on
|
| Heading | Flagged |
|---|---|
Temporal Go technical resources |
no |
Temporal .NET technical resources |
yes |
Temporal NET technical resources |
yes |
Vale tokenizes away the leading dot, so NET reads as a stray capitalised word and the .NET entry already in Temporal.Headings's exception list never matches. The heading is already sentence case; nothing about it is wrong.
Rewording the heading would paper over a rule bug that will keep firing on every .NET page. The root fix is adding NET to the exception list, which is #5140's subject, so I am doing it there rather than here.
Vale tokenizes the leading dot away, so the ".NET" entry never matches the word it actually sees. Every sentence-case heading naming the SDK was therefore flagged: "Temporal .NET technical resources" is reported while the identical Go heading is not. Clears 8 false positives (367 -> 359) without weakening the rule -- "Temporal .NET Technical Resources" is still flagged, as is any other real title-case heading. Surfaced by reviewdog on #5179, where the pre-existing hit on docs/develop/dotnet/index.mdx moved into diff context.
Draft for #5144. The approach works and is verified end to end; what needs a decision before this merges is listed at the bottom.
The problem, as of this week
#5118 added 19 Serverless Workers pages across 7 SDKs on Aug 20. Landing-page links to that feature afterwards:
A documented feature was unreachable from six of seven SDK landing pages. That is the issue in one data point, and it happened after the analysis that prompted this PR — not historically.
What this does
Wraps each
## [Section](url)bullet list on the 8 landing pages in markers, and fills it fromsidebars.js:yarn sidebar-linksregenerates;yarn check:sidebar-linksfails CI when a list is stale.This run adds 11 links, including
Serverless Workersto all six SDKs that were missing it:Insert-only, deliberately
The sidebar decides which pages appear. It does not decide the link text or the order.
I built full generation first and measured it. On the section index pages it would have fixed 5 gaps at the cost of 7 deleted links — including an external
learn.temporal.iotutorial living inside a section list — and 37 rewritten labels, several against the sentence-case rule inreadme/STYLE.md(Feature guide→Feature Guide,Side effects→Side Effects). The sidebar even contradicts itself: one page wantedAsynchronous Activity completion→...Completion, another the reverse.So an entry already listed keeps its text and position, a missing entry is inserted next to its sidebar sibling, and a line the sidebar doesn't know about is preserved.
Python's Integrations section keeps Langfuse, OpenBox, Parseable, Pydantic AI and Tenuo, none of which are in the sidebar.
Why generated text, not a React component
scripts/mdx-to-md.mjs:100registersDocCardListasstrip-block. A component would blank these links inllms-full.txtand every per-page.mdunless someone also wrote and maintained ascripts/component-handlers/handler — andreadme/MARKDOWN_PIPELINE.md:174-193already flags that component/handler duplication as debt.This is not hypothetical.
GuidesGridwas never wired in, sobuild/guides.mdis 225 bytes with zero guide links today andreadme/COMPONENT_REGISTRY.md:48marks itUNKNOWN.Markers are MDX expression comments, which
transformMdxalready strips, so the bullets survive as ordinary Markdown. Verified in the built output:Untouched
Headings that are not sidebar categories —
## Install and get started,## Temporal <X> technical resources,## Get connected with the Temporal <X> community— get no markers, so their 58 external links stay hand-written. Nested leaves (serverless-workers/aws-lambda,cloud-run) stay one click deeper, which is the existing convention for a landing page.Coverage reporting
Markers are opt-in, so a green check with thin coverage would read as "no drift" when it means "no coverage."
--checktherefore also lists pages still hand-maintaining a list:A warning, not a failure: a page with real prose is allowed a hand-written list, and marker-absence is how it says so. That is also why this needs no baseline file, unlike
bin/orphan-pages-baseline.json.Checks
yarn buildpasses; new links verified in both the HTML and the LLM.mdyarn test— 9 new tests inbin/generate-sidebar-link-lists.test.js, plus a case asserting every SDK section index page resolves to a sidebar categoryyarn check:orphans,yarn lint:mermaid,check-redirects-for-moved-pages: cleanvale --config .vale-ci.inion the 8 changed pages: 0 errors, 0 warnings. One pre-existing suggestion ondotnet/index.mdx(Temporal .NET technical resources) is unchanged from main — line number shifted only. It looks like a Vale tokenization artifact on.NET, worth a look alongside Add missing proper nouns to the Temporal.Headings exception list #5140.Decisions this needs
go/index.mdxhas a prose block no other SDK ever got in 4.5 months, a tracked 8-SDK sweep landed "non-retryable by design" on 7 of 8 (ruby missed), and of 117 commits touching an SDK landing page in the last 18 months, 52 (44%) touched exactly one and 3 (2%) touched all eight. Also relevant:onBrokenLinks: 'throw'means every link here is machine-checked, and prose would not be.check:sidebar-linksblock CI or advise? It is wired as a script only; no workflow added yet.Review notes (two passes over this PR)
Five defects found and fixed in
abb4d4cpreservedcount wasexisting.length - sidebarUrls.sizesection=resolved ambiguous matches silentlyQuickstartexists under several sections; it picked whichever came first in traversal. Now refuses and points at the URL form< 2linksworkers/index.mdx— the pages most likely to be missing an entry, since a one-link list is thinner than a ten-link one. Coverage reporting went 42 → 52 pagesno category labelledprocessFilehad no testsIt has five now: unmatched
SIDEBAR-LIST-END, a page no sidebar category links to, the guarantee that content outside the markers never changes, no-op on an already-current page, and URL-form resolution where heading text differs from the sidebar label. Suite is 14 tests.The honest cost: 116 marker lines for 12 link lines
The "125 insertions, 0 deletions" figure above is accurate but flattering. Broken down:
93% of this diff is scaffolding. The case for paying it is that markers are a one-time cost that converts an ongoing manual burden into an enforced one — 11 links today, but the drift rate is what matters, and #5118 shows it recurring. The case against is 116 lines of comment noise in reader-facing source for 12 links.
A marker-free alternative exists and is worth weighing before this merges: infer the managed region from the
## [Section](url)heading itself, since on a landing page every linked-H2 bullet list is a sidebar mirror. That would delete all 116 lines. The trade is that it becomes implicit — a page gets no way to say "this list is deliberately hand-written," which is exactly what marker-absence expresses today, and it's why the 16 content-bearing section index pages can opt out for free. I have not built it; it is a design fork rather than a defect, and it is a reasonable thing to prefer.Verified across all 8 SDKs, not just one
Earlier I had only checked Java. All eight landing pages: markers absent from the rendered HTML and the LLM
.md, with 22-55 bullets surviving in each.md.