-
Notifications
You must be signed in to change notification settings - Fork 158
docs: revamp World documentation pages #763
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
- Add dedicated world detail pages at /worlds/[id] with MDX-driven content - Create WorldDetailHero, WorldDetailToc, WorldTestingPerformance components - Add benchmark history charts and test summary links - Rewrite local-world, postgres-world, and vercel-world MDX with cleaner structure - Use h3 headings for configuration options instead of tables/accordions - Add WorldDataProvider context for passing world data to MDX components - Add example field to worlds-manifest for linking to example repos - Update worlds index page design
|
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📊 Benchmark Results
workflow with no steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Express | Nitro workflow with 1 step💻 Local Development
▲ Production (Vercel)
🔍 Observability: Express | Next.js (Turbopack) | Nitro workflow with 10 sequential steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Nitro | Express Promise.all with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) Promise.all with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Nitro | Express Promise.race with 10 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Next.js (Turbopack) | Express Promise.race with 25 concurrent steps💻 Local Development
▲ Production (Vercel)
🔍 Observability: Next.js (Turbopack) | Express | Nitro Stream Benchmarks (includes TTFB metrics)workflow with stream💻 Local Development
▲ Production (Vercel)
🔍 Observability: Nitro | Express | Next.js (Turbopack) SummaryFastest Framework by WorldWinner determined by most benchmark wins
Fastest World by FrameworkWinner determined by most benchmark wins
Column Definitions
Worlds:
|
🧪 E2E Test Results❌ Some tests failed Summary
❌ Failed Tests🌍 Community Worlds (17 failed)mongodb (1 failed):
redis (1 failed):
starter (14 failed):
turso (1 failed):
Details by Category✅ ▲ Vercel Production
✅ 💻 Local Development
✅ 📦 Local Production
✅ 🐘 Local Postgres
✅ 🪟 Windows
❌ 🌍 Community Worlds
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR revamps the World documentation by creating dedicated detail pages for official worlds (local, postgres, vercel) with MDX-driven content. It introduces new components for world detail pages, benchmark history visualization with interactive charts, and a redesigned worlds index page with a 3D globe visual.
Changes:
- Created dedicated
/worlds/[id]routes with MDX content for official worlds and template components for community worlds - Added benchmark history charts showing performance trends over releases/commits with clickable data points
- Restructured world documentation with cleaner h3 headings for configuration options instead of tables
- Added TOC generation from MDX headings and world data provider context for component communication
Reviewed changes
Copilot reviewed 31 out of 32 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| worlds-manifest.json | Added example field for linking to example repositories |
| package.json | Added cobe dependency (0.6.5) for 3D globe visualization |
| next.config.ts | Added redirects from old /docs/deploying/world/* paths to new /worlds/* routes |
| worlds-data.ts | Enhanced to extract framework-specific E2E data, workflow timing metrics, and added single world lookup functions |
| types.ts | Added framework E2E breakdown types, workflow timing fields, benchmark10SeqMs metric, and formatTime utility |
| WorldDetailHero.tsx | New hero component for world detail pages with E2E/benchmark summary and quick links |
| WorldDetailToc.tsx | New TOC component with intersection observer for active section highlighting |
| WorldTestingPerformance.tsx | New component displaying E2E test results and benchmark tables with history chart integration |
| WorldDataProvider.tsx | New context provider for sharing world data between MDX and client components |
| WorldCardSimple.tsx | New simplified card component for worlds index page with E2E/PERF metrics footer |
| Globe.tsx | New interactive 3D globe component using COBE library |
| BenchmarkHistoryChart.tsx | New dialog component showing performance trends over time with releases/commits toggle |
| local-world.mdx | Rewritten with cleaner structure, h3 config options, and Testing & Performance section |
| postgres-world.mdx | Rewritten with installation steps, framework-specific examples, and detailed configuration |
| vercel-world.mdx | Rewritten with simplified auto-configuration explanation and versioning details |
| worlds/page.tsx | New worlds index page with globe hero, world cards grid, and "What is a World?" section |
| worlds/[id]/page.tsx | New dynamic world detail page supporting both MDX and template rendering |
| worlds/compare/page.tsx | New benchmark comparison page with tables and charts |
| benchmark-history/route.ts | New API route fetching historical benchmark data from gh-pages commits |
| generate-docs-data.js | Enhanced to extract workflow timing metrics (min/max/ttfb/slurp) from benchmark results |
Files not reviewed (1)
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return ( | ||
| <nav className="space-y-1"> | ||
| <p className="font-medium text-sm mb-2">On this page</p> | ||
| {items.map((item) => ( | ||
| <a | ||
| key={item.id} | ||
| href={`#${item.id}`} | ||
| className={cn( | ||
| 'block text-sm py-1 border-l-2 pl-3 transition-colors', | ||
| activeId === item.id | ||
| ? 'border-primary text-foreground font-medium' | ||
| : 'border-transparent text-muted-foreground hover:text-foreground hover:border-muted-foreground' | ||
| )} | ||
| > | ||
| {item.title} | ||
| </a> | ||
| ))} | ||
| </nav> | ||
| ); | ||
| } |
Copilot
AI
Jan 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When items array is empty, this component renders a nav with just the "On this page" heading but no links. While not necessarily broken, consider adding a conditional render or early return if items.length === 0 to avoid rendering an empty navigation section.
| const fileRes = await fetch( | ||
| `https://raw.githubusercontent.com/${REPO}/${ghPagesSha}/${FILE_PATH}`, | ||
| { next: { revalidate: 3600 } } | ||
| ); | ||
|
|
||
| if (!fileRes.ok) return null; | ||
|
|
||
| return (await fileRes.json()) as CIResultsData; |
Copilot
AI
Jan 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The JSON parsing at line 87 doesn't handle malformed JSON responses. If the GitHub API returns invalid JSON, this will throw an unhandled error. Consider wrapping the await fileRes.json() in a try-catch or adding validation.
| const ghPagesCommits = (await ghPagesCommitsRes.json()) as GitHubCommit[]; | ||
|
|
||
| // Fetch benchmark data for each gh-pages commit in batches | ||
| const BATCH_SIZE = 10; | ||
| for (let i = 0; i < ghPagesCommits.length; i += BATCH_SIZE) { | ||
| const batch = ghPagesCommits.slice(i, i + BATCH_SIZE); | ||
| const results = await Promise.all( | ||
| batch.map(async (ghCommit) => { | ||
| const data = await fetchBenchmarkFile(ghCommit.sha); | ||
| if (!data || !data.commit) return null; | ||
|
|
||
| return { | ||
| ghPagesSha: ghCommit.sha, | ||
| mainCommitSha: data.commit, | ||
| timestamp: data.lastUpdated, | ||
| data, | ||
| }; | ||
| }) | ||
| ); | ||
|
|
||
| for (const result of results) { | ||
| if (result && !snapshotMap.has(result.mainCommitSha)) { | ||
| // Only keep the first (most recent) benchmark for each main commit | ||
| snapshotMap.set(result.mainCommitSha, result); | ||
| } | ||
| } |
Copilot
AI
Jan 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, the JSON parsing at line 120 for gh-pages commits doesn't handle malformed JSON responses. Consider adding error handling for the await ghPagesCommitsRes.json() call.
| const ghPagesCommits = (await ghPagesCommitsRes.json()) as GitHubCommit[]; | |
| // Fetch benchmark data for each gh-pages commit in batches | |
| const BATCH_SIZE = 10; | |
| for (let i = 0; i < ghPagesCommits.length; i += BATCH_SIZE) { | |
| const batch = ghPagesCommits.slice(i, i + BATCH_SIZE); | |
| const results = await Promise.all( | |
| batch.map(async (ghCommit) => { | |
| const data = await fetchBenchmarkFile(ghCommit.sha); | |
| if (!data || !data.commit) return null; | |
| return { | |
| ghPagesSha: ghCommit.sha, | |
| mainCommitSha: data.commit, | |
| timestamp: data.lastUpdated, | |
| data, | |
| }; | |
| }) | |
| ); | |
| for (const result of results) { | |
| if (result && !snapshotMap.has(result.mainCommitSha)) { | |
| // Only keep the first (most recent) benchmark for each main commit | |
| snapshotMap.set(result.mainCommitSha, result); | |
| } | |
| } | |
| try { | |
| const ghPagesCommits = (await ghPagesCommitsRes.json()) as GitHubCommit[]; | |
| // Fetch benchmark data for each gh-pages commit in batches | |
| const BATCH_SIZE = 10; | |
| for (let i = 0; i < ghPagesCommits.length; i += BATCH_SIZE) { | |
| const batch = ghPagesCommits.slice(i, i + BATCH_SIZE); | |
| const results = await Promise.all( | |
| batch.map(async (ghCommit) => { | |
| const data = await fetchBenchmarkFile(ghCommit.sha); | |
| if (!data || !data.commit) return null; | |
| return { | |
| ghPagesSha: ghCommit.sha, | |
| mainCommitSha: data.commit, | |
| timestamp: data.lastUpdated, | |
| data, | |
| }; | |
| }) | |
| ); | |
| for (const result of results) { | |
| if (result && !snapshotMap.has(result.mainCommitSha)) { | |
| // Only keep the first (most recent) benchmark for each main commit | |
| snapshotMap.set(result.mainCommitSha, result); | |
| } | |
| } | |
| } | |
| } catch (error) { | |
| console.error('Failed to parse gh-pages commits JSON', error); | |
| return snapshotMap; |
| // Fetch benchmark data for each gh-pages commit in batches | ||
| const BATCH_SIZE = 10; | ||
| for (let i = 0; i < ghPagesCommits.length; i += BATCH_SIZE) { | ||
| const batch = ghPagesCommits.slice(i, i + BATCH_SIZE); | ||
| const results = await Promise.all( | ||
| batch.map(async (ghCommit) => { | ||
| const data = await fetchBenchmarkFile(ghCommit.sha); | ||
| if (!data || !data.commit) return null; | ||
|
|
||
| return { | ||
| ghPagesSha: ghCommit.sha, | ||
| mainCommitSha: data.commit, | ||
| timestamp: data.lastUpdated, | ||
| data, | ||
| }; | ||
| }) | ||
| ); | ||
|
|
||
| for (const result of results) { | ||
| if (result && !snapshotMap.has(result.mainCommitSha)) { | ||
| // Only keep the first (most recent) benchmark for each main commit | ||
| snapshotMap.set(result.mainCommitSha, result); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| return snapshotMap; |
Copilot
AI
Jan 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The batch processing loop processes all gh-pages commits (up to 100) without any upper bound on memory usage. If there are many commits, this could create a large number of parallel fetch requests. Consider adding a limit to the total number of commits processed or adding more granular error handling to prevent memory issues.
docs/components/worlds/Globe.tsx
Outdated
| const globe = createGlobe(canvasRef.current!, globeConfig); | ||
|
|
Copilot
AI
Jan 10, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The canvasRef.current could be null when createGlobe is called. While the non-null assertion operator (!) is used, this could cause a runtime error if the component unmounts or the ref isn't set before the effect runs. Add a null check before calling createGlobe.
| const globe = createGlobe(canvasRef.current!, globeConfig); | |
| const canvas = canvasRef.current; | |
| if (!canvas) { | |
| return () => { | |
| window.removeEventListener('resize', onResize); | |
| }; | |
| } | |
| const globe = createGlobe(canvas, globeConfig); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| samples: latestPoint?.samples, | ||
| current, | ||
| trendPercent, | ||
| ttfb: latestPoint?.ttfb, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| if (!fileRes.ok) return null; | ||
|
|
||
| return (await fileRes.json()) as CIResultsData; | ||
| } catch { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Update title format to '{Name} World | Workflow DevKit'
- Update worlds index page title to 'Worlds | Workflow DevKit'
- Improve world descriptions in worlds-manifest.json for better SEO
- Add dynamic OG image generation at /worlds/[id]/og
- Add openGraph and twitter metadata to world detail pages
| const pointerInteracting = useRef<number | null>(null); | ||
| const pointerInteractionMovement = useRef(0); | ||
| const [size, setSize] = useState(1200); | ||
| const { resolvedTheme } = useTheme(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
- Replace route-based og/route.tsx with opengraph-image.tsx file convention - Remove runtime = 'edge' to allow generateStaticParams for static generation - Simplify page.tsx metadata (Next.js auto-detects opengraph-image.tsx)
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
Added dedicated worlds page to show all available worlds incuding e2e testbench pass rate and performance benchmarking
Added historic performance benchmarking over last 30 commits/releases on github with request caching (should probably be ISR / PPR since these can be caluclated at build time and don't need to be re-fetched)
Rewrote the Local, Postgres and Vercel world documentation pages to follow a standard structure with config, observability, benchmarking notes
TODOs
Preview
Worlds Page
Postgres Docs (also check the other worlds)


