Skip to content

feat(docs): give every docs page its own URL and prerendered HTML - #976

Merged
Ishaan Gangwani (ishaan1124) merged 1 commit into
mainfrom
seo/docs-paths
Oct 13, 2026
Merged

Ishaan Gangwani (ishaan1124) merged 1 commit into
mainfrom
seo/docs-paths

Conversation

@ishaan1124

Copy link
Copy Markdown
Member

Why

The docs used hash routing (/docs/#/openscience/<page>). Search engines ignore the fragment, so all ~70 pages counted as one URL whose HTML was an empty shell. Docs are a major ranking surface for developer tools; this makes each page indexable on its own.

What

Docs

  • Pages live at /docs/<page> (navigation.ts: parseRoute reads paths and still parses legacy hash routes; pageHref emits paths)
  • script/prerender.ts renders every page in docs.json to dist/<page>.html with its own <title> (documentTitle, ≤60 chars), description, canonical, OG/Twitter tags and TechArticle + BreadcrumbList JSON-LD; writes a noindex 404.html and sitemap.xml
  • main.tsx redirects old links (/docs/#/openscience/x, /docs/#<renamed>, /docs/<renamed>) via movedHref before hydrating; the CLI, apps and READMEs keep working
  • In-app navigation uses the History API (internal links are intercepted; back/forward via popstate)
  • Theme: inline script applies the stored theme before paint; useTheme starts light for hydration and syncs in a layout effect
  • export.ts: llms files use the new URLs
  • Builds fail if a page's title is over 60 chars, its description over 155, or it doesn't have exactly one h1

Landing

  • Shorter titles for home and benchmark, benchmark description within 155; page-level WebPage/BreadcrumbList JSON-LD; same build check
  • docs() links to /docs/<page>; vercel.json rewrites unknown docs paths to the docs 404 and 308s /docs/ to /docs; robots.txt lists /docs/sitemap.xml

Verified locally

  • bun run test:docs equivalents: bun test ./test (8 pass, routes + legacy redirects + titles), tsc --noEmit
  • Playwright e2e/docs.spec.ts (updated for path URLs, still covers legacy hash links): 6/6 pass, including all 70 pages rendering with the right h1/title and no page errors
  • Hydration: no React errors on prerendered pages in light and dark theme; the not-found markup is identical for any unknown path, so 404.html hydrates cleanly
  • Full landing build (docs build → landing build): 70 docs pages + 404 + sitemap land in dist/docs

Made with Cursor

Docs pages move from /docs/#/openscience/<page> to /docs/<page>. Each page is
rendered at build time with its own title, description, canonical URL and
TechArticle + BreadcrumbList JSON-LD, so search engines can index and rank
pages individually instead of seeing one /docs shell.

- old hash links and renamed pages redirect in the browser (movedHref)
- navigation stays in place: internal links use the History API
- unknown /docs paths serve a noindex not-found page; /docs/sitemap.xml lists all pages
- the stored theme is applied by an inline script before the prerendered page paints
- llms.txt and llms-full.txt use the new URLs
- builds fail on a page with a title over 60 characters, a description over 155, or not exactly one h1

Landing: titles within 60 characters (home, benchmark), benchmark description
within 155, page-level WebPage/BreadcrumbList JSON-LD, the same build check,
docs() links to /docs/<page>, robots.txt lists the docs sitemap.

Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel

vercel Bot commented Oct 13, 2026 •

Copy link
Copy Markdown

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

Project Deployment Actions Updated
openscience Ready Ready Preview Oct 13, 2026 2:53am UTC

Request Review

@ishaan1124
Ishaan Gangwani (ishaan1124) merged commit d92a214 into main Oct 13, 2026
8 checks passed
@ishaan1124
Ishaan Gangwani (ishaan1124) deleted the seo/docs-paths branch October 13, 2026 02:55

This branch was successfully deployed

1 active deployment
Preview — c2693188 Deployed Oct 13, 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.

1 participant