fix: implement SDK-specific routes for SEO and agent discovery - #909
fix: implement SDK-specific routes for SEO and agent discovery#909davidmytton wants to merge 14 commits into
Conversation
Introduce the variant type system, Astro component wrappers, and visual regression tests that validate per-SDK routes render identically to legacy ?f= query parameter pages. - Add ArcjetSdkVariant type and helpers (sdkVariants, sdksWithVariants, sdkVariantFromPathname, legacyKeyFromPathname, pathnameForSdkVariant) - Rename React components to *React.tsx and wrap with Astro server components (SlotByFramework, TextByFramework, FrameworkLinks) that render statically on SDK routes and delegate to React on legacy pages - Update MDX imports to use .astro wrappers and remove client:load - Add stub MDX files for variant get-started pages (bun+hono, node+express, node+hono, python+fastapi, python+flask) - Add Playwright screenshot parity tests covering all 16 page types across all supported frameworks (114 tests) Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Pick up PR #773 infrastructure and fix the Vercel preview skeleton issue by adding Astro wrappers for page titles, initializing the framework store from SDK pathnames, and removing client:load from remaining MDX imports. SDK-scoped routes now self-canonicalize, include plus-variant paths in the content loader, preserve variant prefixes in sidebar links, and set framework-specific document titles at request time. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Remove stub MDX wrappers that re-imported get-started via nested MDX components. The content loader now owns all plus-variant routes directly, which avoids pathname ambiguity and 404s when stubs and loader entries diverge. Show variant labels such as "Bun + Hono" in the SDK switcher on plus-variant pages. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
There was a problem hiding this comment.
Arcjet Review — 🟢 Low Risk
Decision: Approved
Rationale: Documentation infrastructure change with no security-sensitive surface. Introduces Astro wrappers for framework-switching components so SDK-scoped routes (/sdk/:sdk/... and plus-variant routes) render statically, updates the content loader to emit plus-variant duplicates with self-canonical URLs, and expands metadata/sitemap/llms.txt to cover the new URLs. Well-tested: 114 parity snapshots plus 49 new unit/coverage tests. No auth, dependency, infra, or migration surface. Size is large primarily because of binary snapshots.
Summary of Changes
Makes SDK-specific routes (/sdk/:sdk/... and plus-variant /sdk/:sdk/plus/:variant/...) render framework-specific content server-side with self-canonical URLs, includes them in the sitemap, and lists SDK-scoped get-started URLs in llms.txt. Adds Astro wrappers for SlotByFramework, TextByFramework, TitleByFramework, and FrameworkLinks that short-circuit client-side hydration on SDK routes; renames the React implementations to *React.tsx. Introduces sdkVariants, sdkVariantFromPathname, legacyKeyFromPathname, pathnameForSdkVariant, and sdkDisplayLabelFromPathname helpers in src/lib/sdk.ts. The content loader stops adding noindex / sitemap: false on scoped duplicates and instead points canonical at the scoped URL itself. Tests cover parity, SEO metadata, sitemap inclusion, llms.txt links, and switcher labels.
Notes
PR is ~1000+ lines but the bulk is 114 binary snapshot files and repetitive client:load removals across MDX files. Actual reviewable logic is small and well-scoped. One thing worth double-checking manually: src/content.config.ts now indexes every doc entry under every sdk/* and sdk/*/plus/* prefix — that's a substantial expansion of the crawlable URL surface, called out in a code review comment.
Review: a8700463 | Model: anthropic/claude-opus-4-7 | Powered by Arcjet Review
Add hrefForLegacyFrameworkKey and legacyFrameworkQueryRedirect helpers so framework buttons, the switcher, ToSdk links, sidebars, and vercel.json redirects all target /sdk/... paths. Middleware 301-redirects legacy ?f= URLs for HTTP SDKs and strips the param on SDK routes. Guard-only frameworks on non-get-started pages still use ?f= for client switching. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Remove legacyFrameworkQueryRedirect from middleware. Generate 204 Vercel redirect rules from sdk.ts for legacy ?f= URLs on known doc paths, plus a catch-all to strip ?f= from /sdk/:path* routes. Sync astro.config path redirects to SDK destinations and add npm run generate:legacy-f-redirects. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Use set:html for framework titles, derive SlotByFramework slots from prefs, scope content loader duplicates to framework-specific entries, and narrow ArcjetSdkVariant.key to a string-literal union. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Compare normalised .sl-markdown-content text between legacy ?f= pages and SDK routes instead of matching both against the same snapshot file. Seed Astro island hydration on SDK get-started pages so SelectableContent tabs render before parity checks run. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Mark legacy framework hub pages and plus-variant SDK routes as noindex while keeping base SDK routes indexable with self-canonical URLs. Extend legacy ?f= redirect coverage to filters/reference, rate-limiting/reference, nosecone, and sensitive-info paths. Exclude noindex URLs from the sitemap, and migrate llms-full.txt quick starts to SDK-scoped URLs with trailing slashes. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Add coverage for legacy hub noindex, plus-variant noindex, sitemap omissions, llms-full.txt SDK URLs, extended ?f= redirect paths, and sitemap exclusion helpers. Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
…on paths Python has no base legacy framework key, so bare /sdk/python/ routes fell back to Next.js content and the SDK switcher only listed "Python". - Expand SDK switcher to list plus-variants (Python + FastAPI/Flask, etc.) - Skip generating base scoped entries for variant-only SDKs - Redirect bare /sdk/python/ paths to the FastAPI plus-variant - Route pathnameForSdk and scopeHrefToSdk through default variants Co-authored-by: David Mytton <davidmytton@users.noreply.github.com>
Summary
/sdk/python/...content entries and redirect those URLs to/sdk/python/plus/fastapi/...pathnameForSdk,scopeHrefToSdk) to route variant-only SDKs through their default plus-variantContext
Python is the only HTTP SDK without a base
legacyFrameworkKey. Bare/sdk/python/get-started/could not resolve a framework slot and hydrated with the defaultnext-jscontent.