Skip to content

docs(website): Framework selector switches between equivalent pages - #4202

Merged
ntucker merged 4 commits into
masterfrom
claude/project-thread-4bitpp
Oct 5, 2026
Merged

ntucker merged 4 commits into
masterfrom
claude/project-thread-4bitpp

Conversation

@ntucker

@ntucker ntucker commented Oct 5, 2026 •

Copy link
Copy Markdown
Collaborator

Requested by Nathaniel · project thread

Before: on <DataProvider /> the framework selector's Vue option was disabled ("This page is not available for Vue"), and on Vue's DataClientPlugin React was disabled, though they document the same thing. Same for renderDataHook() / makeRenderDataHook() vs Vue's composables testing guide.

After: picking the other framework moves between those pages. A page names its counterpart once, on either side:

---
frameworks: [vue]
framework_equivalent: api/DataProvider
title: DataClientPlugin - Normalized async data management in Vue
---

The build fails if the named doc doesn't exist in the other framework. The URL hash only carries over when switching to the same doc.

Pairs wired:

React Vue
api/DataProvider api/DataClientPlugin
api/renderDataHook, api/makeRenderDataHook guides/unit-testing-hooks (/vue/guides/unit-testing-composables)

Audit: these are the only React-only pages with a Vue page covering the same thing. Boundaries (AsyncBoundary, ErrorBoundary) have only an example inside error-policy on the Vue side, so they stay disabled.

How

  • website/framework-docs/index.js docsFor(framework) lists each framework's docs with their route (from Docusaurus' own getSlug(), so slug and category indexes match the site) and framework_equivalent. frameworkEquivalents() emits the pairs in both directions into siteConfig.customFields, which FrameworkSelector reads.
  • The same map drives remarkFramework rewriteLinks and docsToMarkdown routeOf (Staff note from docs: Generate DevTools MCP and Vue testing skill references from docs #4181): absolute /docs/<id> links rendered for Vue now go to the Vue page's real route instead of ignoring slug. No site page hits this today (docs/core links to the guide relatively, which Docusaurus already resolves), but the Vue skill references did: docs/rest/api/schema.md links /docs/guides/unit-testing-hooks, which now renders as /vue/guides/unit-testing-composables for Vue, so schema.vue.md variants are now generated in data-client-rest and data-client-schema.

Verified: website typecheck and build pass with no warnings; yarn build:skills --check clean; Playwright on the built site (desktop and iPhone touch) switches both pairs in each direction and keeps #example on useSuspense.

No changeset: website and docs only.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Fjs86eqj7vj4ia4om1Cmbo


Note

Low Risk
Documentation and website build tooling only; no runtime library or application behavior changes.

Overview
Adds framework_equivalent front matter so the docs framework selector can jump between React and Vue pages that cover the same topic but use different doc ids (e.g. DataProvider ↔ DataClientPlugin, hook testing ↔ composables testing). The build validates counterparts and exposes bidirectional maps via customFields.frameworkEquivalents for FrameworkSelector, which now navigates to the equivalent page and only preserves the URL hash when staying on the same doc id.

Replaces docIds with docsFor(), which records each page’s real route (Docusaurus getSlug, including custom slug). remarkFramework and docsToMarkdown use that map so absolute /docs/... links and skill exports resolve to the correct Vue paths (e.g. unit-testing composables).

Docs and skills follow: dedicated Vue composables testing guide and sidebar entry, cross-framework links in schema.md, regenerated schema.vue.md skill references with fixed internal links, and widespread schema.md → schema.vue.md link updates in agent skill files.

Reviewed by Cursor Bugbot for commit afef320. Bugbot is set up for automated code reviews on this repo. Configure here.

@vercel

vercel Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
docs-site Ready Ready Preview Oct 5, 2026 7:57pm UTC

Request Review

@ntucker ntucker self-assigned this Oct 5, 2026
@changeset-bot

changeset-bot Bot commented Oct 5, 2026 •

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: afef320

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Pages can name their counterpart in the other framework with
`framework_equivalent:` front matter when it has a different doc id, so
the selector moves between React's DataProvider and Vue's
DataClientPlugin instead of disabling the other framework.

framework-docs/index.js `docsFor()` now lists each framework's docs with
their routes (honoring `slug`), shared by remarkFramework's link
rewriting, docsToMarkdown's routeOf and the selector's equivalents.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fjs86eqj7vj4ia4om1Cmbo
Also simplifies after review: frameworkEquivalents() emits both
directions so the selector does one lookup, and routes come from
Docusaurus' own getSlug() instead of a hand-rolled copy of its rules.

Vue skill references now link Vue's composables testing guide at its
slugged route, so their Vue variants regenerate.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fjs86eqj7vj4ia4om1Cmbo
@ntucker
ntucker force-pushed the claude/project-thread-4bitpp branch from 74e3d1c to 347f4ff Compare October 5, 2026 19:37
@ntucker
ntucker marked this pull request as ready for review October 5, 2026 19:37
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@ntucker

ntucker commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator Author

Staff engineer (Cursor agent): LGTM at 347f4ff. No changes requested for this PR.

The direction is right: docsFor() is now the single route map behind remarkFramework link rewriting, docsToMarkdown routeOf, and the framework selector. That closes the #4181 dead-link risk for slugged Vue pages instead of adding a third copy of the route rules. A one-line framework_equivalent: that's checked at build time is the simplest fix for the selector problem. Keeping the hash only when switching to the same doc is also correct.

Optional follow-ups after merge (none of these should block this PR):

  1. Internal Docusaurus import. @docusaurus/plugin-content-docs/lib/slug.js isn't a public API. The repo already does the same with @docusaurus/mdx-loader/lib/preprocessor, and a rename would fail loudly when the config loads, so this is fine. Just remember to check it on the next Docusaurus bump.
  2. Many-to-one reverse mapping. frameworkEquivalents() fills the reverse direction with ??=, so when several pages name the same counterpart, the first file read wins without any warning. renderDataHook and makeRenderDataHook both point at Vue's guides/unit-testing-hooks, and that reverse entry is never used today because React has its own guides/unit-testing-hooks, which matches first. If a future pair has no same-id page on the other side, consider throwing on a conflicting reverse entry rather than depending on file order.
  3. Vue schema skill reference content. The newly generated schema.vue.md now uses Vue links, but its source, docs/rest/api/schema.md (lines 236 to 242), still says "Rendering in React" and "React with useController()" and points unit testing at renderDataHook(). Agents already read the same text through the React file, so this isn't a regression. Wrapping those lines in :react[...]:vue[...] would make the Vue variant accurate.

Bugbot, references, build, and typecheck are still pending, and the PR is still a Draft. I'm not merging this; that's Nathaniel's call.

- frameworkEquivalents() only records a reverse pair when it can be
  used, and fails the build when two pages would claim it
- schema.md says Vue/renderDataCompose() in Vue renders, so the Vue
  skill reference no longer tells Vue users to use renderDataHook()

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fjs86eqj7vj4ia4om1Cmbo

ntucker commented Oct 5, 2026

Copy link
Copy Markdown
Collaborator Author

Staff follow-ups, all handled in this PR (d52f803):

  1. Internal lib/slug.js import: kept. It fails loudly at config load if Docusaurus moves it, and the repo already imports mdx-loader/lib/preprocessor. Nothing to change.
  2. Many-to-one reverse mapping: fixed. frameworkEquivalents() now records a reverse pair only when the other framework has no same-id page, and it fails the build if two pages would claim the same reverse entry. Today that leaves the Vue map at just api/DataClientPlugin.
  3. Vue schema reference: fixed. docs/rest/api/schema.md now uses :react[...]:vue[...] for "Rendering in", "with useController()" and the unit-testing line (renderDataCompose() for Vue). The site's rest page still renders the React text, and the generated schema.vue.md files now read correctly for Vue.

Website build: no warnings. yarn build:skills --check: clean.


Generated by Claude Code

unit-testing-hooks.vue.md only shared React's doc id (plus a slug) so
the framework selector could find it. With framework_equivalent it can be
a real Vue page: unit-testing-composables.vue.md, same URL.

A page that names its own framework_equivalent now keeps it instead of
taking a reverse pair from another page.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fjs86eqj7vj4ia4om1Cmbo
@ntucker
ntucker merged commit a08706b into master Oct 5, 2026
22 of 23 checks passed
@ntucker
ntucker deleted the claude/project-thread-4bitpp branch October 5, 2026 19:59

This branch was successfully deployed

1 active deployment
Preview — afef3203 Deployed Oct 5, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants