* docs: make /worlds the canonical home for World docs
The world pages (Local/Postgres/Vercel) and Building a World were
duplicated inside the v4 and v5 docs trees while /worlds/[id] rendered
the v4 copy — hiding v5-only content like multi-region and leaving two
diverging sources of truth.
- Move world docs to an unversioned docs/content/worlds/ collection
(based on the v5 copies, with inline 4.x callouts for factory naming
and 5.x-only env vars), rendered at /worlds/*
- Add /worlds/building-a-world; flatten the docs Deploying section to a
single intro page and drop its Rocket icon
- Point every link, frontmatter ref, and worlds-manifest docs field at
/worlds/*; add redirects for the removed v5 and building-a-world URLs
- Keep world docs on agent-facing surfaces: search, llms.txt,
sitemap.md/.xml, and .md exports now serve the worlds collection
- Extend the docs link linter to validate worlds pages (with heading
anchors) and their outgoing links
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
* docs: version the world docs like the docs trees (v4/v5 switcher)
Instead of a single unversioned copy, world docs now follow the same
versioning strategy as the docs pages: content/worlds/v4 is served at
/worlds/* (current) and content/worlds/v5 at /v5/worlds/*, restoring the
original per-version content. Each world detail page (and Building a
World) renders the docs version switcher — the worlds listing page has
no natural home for it, so it lives on the world pages themselves.
- Render-time href rewriting on v5 pages now covers /worlds/... links
(shared rewriteHrefForVersion helper, also used by the v5 docs and
cookbook routes), and the markdown-export rewrite does the same
- v5 world pages are noindexed with a canonical to /worlds/<id>;
community worlds stay unversioned (/v5/worlds/<id> redirects)
- /v5/docs/deploying/world/* redirects now land on /v5/worlds/*;
/v5/worlds and /v5/worlds/compare redirect to the unversioned pages
- Link linter models the versioned worlds URL spaces (v5 pages resolve
/worlds hrefs against the v5 collection); sitemap.md and the .md
export routes cover /v5/worlds/*
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
* docs: fix v4 multi-region anchor and tighten version-prefix matching
Address PR review:
- The v4 Deploying page linked /worlds/vercel#multi-region, but the
Multi-region section only exists on the v5 world page; use the
explicit cross-version /v5/worlds/vercel#multi-region link (this was
the Docs Links CI failure)
- rewriteHrefForVersion now uses the boundary-checked hasPathPrefix
(shared leaf module lib/geistdocs/path-prefix.ts, also used by
source.ts) instead of bare startsWith
- buildVersionUrl's shared-route fast path is segment-based rather than
substring includes()
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
---------
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* Add AI agent detection and automatic markdown rewrites
When AI agents (Claude, ChatGPT, Cursor, etc.) request docs pages,
the proxy now detects them and transparently rewrites to the markdown
route — matching the geistdocs template default.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* Fix: Missing import for `isAIAgent` in `docs/proxy.ts` causes a ReferenceError at runtime when the AI agent detection code path is reached.
This commit fixes the issue reported at docs/proxy.ts:68
**Bug explanation:**
In `docs/proxy.ts`, the function `isAIAgent` is called on line 68 (`const agentResult = isAIAgent(request)`) within the AI agent detection block (lines 63-87). However, this function was never imported into the file. The function is defined and exported in `docs/lib/ai-agent-detection.ts`, but the import statement was omitted when the AI agent detection feature was added to `proxy.ts`.
This would cause a `ReferenceError: isAIAgent is not defined` at runtime whenever a request matches the condition on lines 64-67 (any request to `/docs` or `/docs/*` that doesn't include `/llms.mdx/`). This is a critical path — every docs page request would hit this code.
**Fix explanation:**
Added the missing import statement: `import { isAIAgent } from '@/lib/ai-agent-detection';` at line 10 of `proxy.ts`, after the existing imports. This correctly resolves the `isAIAgent` reference to the exported function in `docs/lib/ai-agent-detection.ts`.
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
Co-authored-by: molebox <hello@richardhaines.dev>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com>
* Fix og route handling in i18n middleware
* Add docs CI smoke test for OG and sitemap
* Run docs OG checks against Vercel preview
* Refactor docs CI checks and rename smoke test
* Use docs Vercel token for preview checks
* Expand docs OG smoke coverage
* Check docs HTML OG metadata
* changeset
Signed-off-by: voyager14 <21mh124@queensu.ca>
* refactor OG image generation into shared utility
Signed-off-by: voyager14 <21mh124@queensu.ca>
* fix og image height mismatch
Signed-off-by: voyager14 <21mh124@queensu.ca>
* fix: add missing getPageImage and include OG assets in Vercel output
Signed-off-by: voyager14 <21mh124@queensu.ca>
* exclude og in middleware
Signed-off-by: voyager14 <21mh124@queensu.ca>
* fix(docs): wire up OpenGraph images for docs pages
Complete the OG image integration that was started in PR #858:
- Add openGraph.images metadata to docs page generateMetadata using
the getPageImage helper from source.ts
- Add metadataBase to the root layout so Next.js can resolve OG URLs
- Remove unused generatePageMetadata helper from docs-page.tsx
This ensures docs pages like /docs/how-it-works/event-sourcing have
proper OpenGraph images when shared on social media.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
* fix(docs): use dynamic OG image for homepage
The static opengraph-image.png at the app root wasn't being served
because all routes are under [lang]/. Next.js OG images need to be
in the same route segment as the page they apply to.
- Create dynamic opengraph-image.tsx in [lang]/(home)/ using the
shared createOgImage utility
- Remove the unused static opengraph-image.png from app root
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(docs): use dynamic metadataBase for preview deployments
The metadataBase was hardcoded to useworkflow.dev, which caused
preview deployments to generate OG image URLs pointing to production
instead of the preview URL.
Now uses:
- Production: https://useworkflow.dev
- Preview: https://${VERCEL_URL}
- Local dev: http://localhost:3000
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(docs): address PR review comments for OG images
- Fix semibold font weight from 500 to 600 (semibold is weight 600)
- Extract OG_IMAGE_SIZE constant to lib/og/index.tsx for consistency
- Use shared constant in all opengraph-image.tsx files
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(docs): match OG image styling to production design
- Fix title styling: "Workflow:" in white, rest in grey (#888888)
- Remove description from homepage OG image
- Adjust positioning and font size to match expected design
- Reduce text width to prevent overflow
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(docs): add display flex for Satori multi-child divs
Satori requires explicit display: flex on divs with multiple children.
Added flex flex-wrap to the title div containing the two spans.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(docs): simplify OG image layout with stacked title
Use separate divs for "Workflow:" and title instead of trying to
inline them with flex-wrap, which was causing layout issues in Satori.
- "Workflow:" on first line in white
- Title on second line in grey
- Reduced font size slightly to prevent overflow
- Properly stacked with flex-col layout
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(docs): correct OG image positioning below background Workflow: text
The background.png already contains "Workflow:" text, so we only need
to render the dynamic title positioned below it.
- Remove hardcoded "Workflow:" from JSX (it's in the background image)
- Adjust top positioning to 290px to place title below background text
- Restore textWrap: balance for proper text flow
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(docs): align OG title with background Workflow: text
Position and size title to match background image's Workflow: text,
using non-breaking spaces for horizontal offset so title flows inline.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(docs): restore debug border on OG image container
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(docs): add homepage OG route and fix positioning
- Add /og route for homepage OG image (avoids i18n middleware conflict)
- Remove broken opengraph-image.tsx that conflicted with middleware
- Add explicit openGraph metadata to homepage
- Restore debug border for positioning
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(docs): add OG routes for worlds pages
- Add /og/worlds route for worlds listing page
- Add /og/worlds/[id] route for individual world pages
- Remove broken opengraph-image.tsx that conflicted with i18n middleware
- Add explicit openGraph metadata to worlds pages
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* fix(docs): remove badge from worlds OG images
Badge was causing layout issues with title positioning.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add descriptions to AI, foundations, how-it-works, deploying, and observability pages
Add terse descriptions for OG image rendering to:
- 8 AI docs
- 9 foundations docs
- 4 how-it-works docs
- 5 deploying docs
- 1 observability doc
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* docs: add descriptions to API reference, errors, and remaining getting-started pages
Add terse descriptions for OG image rendering to:
- 23 API reference docs (workflow, workflow/api, @workflow/ai, workflow/next)
- 9 errors docs
- 5 getting-started docs (Astro, Express, Fastify, NestJS, Vite)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
---------
Signed-off-by: voyager14 <21mh124@queensu.ca>
Signed-off-by: Pranay Prakash <pranay.gp@gmail.com>
Co-authored-by: voyager14 <21mh124@queensu.ca>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The docs template refactor accidentally removed the SVG and ZIP file
exclusions from the middleware matcher, causing public static assets
like workflow-circle-symbol-light.svg and workflow-circle-symbol-dark.svg
to be processed by the i18n middleware instead of being served directly.
This restores the original behavior where static files are served from
the public folder without middleware interference.
Co-authored-by: Cursor Agent <cursoragent@cursor.com>