Skip to content

Migrate docs to Vocs v2 and Bun#2536

Draft
jcstein wants to merge 6 commits into
mainfrom
codex/jcs/migrate-vocs-v2-bun
Draft

Migrate docs to Vocs v2 and Bun#2536
jcstein wants to merge 6 commits into
mainfrom
codex/jcs/migrate-vocs-v2-bun

Conversation

@jcstein

@jcstein jcstein commented Jun 18, 2026

Copy link
Copy Markdown
Member

Summary

Draft migration of the Celestia docs from Next/Nextra/Yarn to Vocs v2, Vite, and Bun.

This also adds the Eden-style Cloudflare Pages setup: the docs build remains full-static, and worker/index.js is copied into out/public/_worker.js to serve /mcp and /api/mcp on the same origin.

What changed

  • Migrated the docs app to Vocs v2 + Vite + Bun.
  • Reworked generated src/pages compatibility from the existing app/**/page.mdx tree.
  • Updated GitHub Pages and preview workflows for the Vocs out/public output.
  • Added a Cloudflare Pages test deployment workflow and wrangler.jsonc.
  • Added a static Cloudflare Pages MCP Worker matching the Eden docs pattern.
  • Updated the Node API page rendering and OpenRPC spec to v0.31.3.

Validation

Notes

This is draft while we verify the migrated docs surface and decide how to cut over production from the current GitHub Pages deployment to Cloudflare Pages.

@jcstein

jcstein commented Jun 18, 2026

Copy link
Copy Markdown
Member Author

Cloudflare test deploy is live here:

https://codex-jcs-migrate-vocs-v2-bu.celestia-docs-vocs-test.pages.dev/

Latest workflow run after merging origin/main:
https://github.com/celestiaorg/docs/actions/runs/27785780444

Latest immutable deployment URL:
https://6fa33c0d.celestia-docs-vocs-test.pages.dev

Smoke test results from the deployed Pages site:

  • /build/rpc/node-api/ returns 200
  • /api/mcp initialize returns 200
  • /api/mcp notifications/initialized returns 202
  • /api/mcp read_page for /build/rpc/node-api returns # Node API

Notes before switching production to docs.celestia.org:

  • This PR currently deploys to the test Pages project celestia-docs-vocs-test; production should use the final Cloudflare Pages project for Celestia docs.
  • Set CLOUDFLARE_PAGES_PROJECT as a repo variable if the production project name should differ from celestia-docs-vocs-test.
  • Add/verify the docs.celestia.org custom domain on the production Cloudflare Pages project.
  • Update DNS for docs.celestia.org from the current GitHub Pages target to the Cloudflare Pages target once the production deploy is verified.
  • Replace or disable the GitHub Pages production deploy workflow after cutover so two systems are not trying to own the same docs domain.
  • Verify production headers after cutover, especially that branch-preview x-robots-tag: noindex behavior is not present on the production hostname.
  • Keep /api/mcp on the same origin; Vocs' Ask AI menu copies /api/mcp by default, so we do not need Eden's custom mcp.url patch if Cloudflare serves that route.

Comment thread .github/workflows/deploy-cloudflare.yml Fixed
Comment thread .github/workflows/deploy-cloudflare.yml Fixed
Comment thread .github/workflows/deploy-cloudflare.yml Fixed
Comment thread .github/workflows/deploy.yml Fixed
Comment thread .github/workflows/lint.yaml Fixed
Comment thread .github/workflows/lint.yaml Fixed
Comment thread .github/workflows/preview.yaml Fixed
@github-actions

github-actions Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

🚀 Preview Deployment

Your preview is ready: https://celestiaorg.github.io/docs-preview/pr-2536/

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

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 drafts a migration of the Celestia docs site from Next.js/Nextra/Yarn to Vocs v2 on Vite + Bun, updates the build/deploy pipelines accordingly, and introduces a Cloudflare Pages “advanced mode” Worker to serve MCP endpoints on the same origin as the static site.

Changes:

  • Replace Next/Nextra app config with Vocs + Vite + Bun, including a generated src/pages compatibility layer from the existing app/** MDX tree.
  • Add Cloudflare Pages configuration + MCP Worker (served via _worker.js) and update GitHub Actions workflows for the new build output (out/public).
  • Rework the Node API OpenRPC docs page rendering/styling and bump the referenced spec to v0.31.3.

Reviewed changes

Copilot reviewed 42 out of 47 changed files in this pull request and generated 8 comments.

Show a summary per file
File Description
wrangler.jsonc Adds Cloudflare Pages project config pointing at out/public.
worker/index.js Adds Pages Worker implementing MCP JSON-RPC tools backed by static markdown assets.
vocs.config.ts Introduces Vocs site config (nav, sidebar, edit links, full-static).
vite.config.ts Adds Vite + Vocs plugin setup and compatibility aliases.
tsconfig.json Removes Next-specific config; adds Vite client + Node types and new excludes.
src/vocs/root.css Adds global CSS (KaTeX + brand fonts + steps styling).
src/vocs/layout.tsx Adds Vocs root layout with JSON-LD and well-known/LLMs link tags.
src/vocs/compat/nextra-components.tsx Provides Vocs-backed replacements for nextra/components (Callout/Tabs/Steps).
src/vocs/compat/next-link.tsx Provides a minimal next/link compatible anchor wrapper.
src/vocs/compat/next-image.tsx Provides a minimal next/image compatible <img> wrapper.
src/pages.gen.ts Adds generated route typing for Waku/Vocs pages.
scripts/prepare-vocs-pages.mjs Generates src/pages from app/** and applies MDX/frontmatter compatibility transforms.
scripts/generate-llms.js Updates OpenRPC spec path/version and writes outputs to out/public when present.
scripts/check-links.mjs Updates script messaging from Nextra to Vocs.
README.md Updates local dev/build/deploy instructions for Bun/Vocs and Cloudflare Pages.
plugins/remark-replace-variables.mjs Updates plugin docstring wording to remove Nextra-specific phrasing.
package.json Replaces Next scripts with Vite/Vocs + Bun workflows and adds new deps (vocs/waku/vite/wrangler).
next.config.mjs Removes Next.js configuration (no longer used).
mdx-components.js Removes Nextra MDX components wiring (no longer used).
loaders/strip-mdx-route-metadata.cjs Removes Nextra-specific MDX loader workaround.
eslint.config.mjs Replaces eslint-config-next with ESLint v9 + typescript-eslint config.
components/WrapperWithFooter.tsx Removes Nextra wrapper component.
components/FontStyles.tsx Removes Next-specific runtime font injection component.
components/ContentFooter.tsx Switches from Next <Link> to <a> and updates accent color variable.
components/BaseImage.tsx Replaces next/image usage with a plain <img> wrapper.
app/operate/_page._mdx Updates Operate landing content/links to new doc paths.
app/layout.tsx Removes Nextra root layout (replaced by Vocs runtime/layout).
app/build/rpc/node-api/page.mdx Updates Node API page MDX (frontmatter + simplified content).
app/build/rpc/lib/helper.ts Tightens classNames typing and removes an eslint disable.
app/build/rpc/hooks/useDarkMode.ts Updates dark-mode detection from Nextra classes to Vocs theme data attribute.
app/build/rpc/components/RPCMethod.tsx Refactors method card markup/classes and removes Nextra styling assumptions.
app/build/rpc/components/rpc-api.css Adds dedicated CSS styling for the RPC docs UI under Vocs.
app/build/rpc/components/Playground.tsx Refactors Headless UI dialog usage (removes Transition wrappers).
app/build/rpc/components/ParamModal.tsx Refactors modal markup/classes to match new CSS system.
app/build/rpc/components/NotificationModal.tsx Makes notification prop optional with a default value.
app/build/rpc/components/NodeAPIContent.tsx Switches to new CSS, new basePath logic, adds v0.31.3, removes dark-mode prop threading.
app/build/rpc/components/DynamicRPCTOC.tsx Removes Nextra-specific TOC DOM-manipulation workaround.
app/build/rpc/components/CopyIcon.tsx Simplifies icon sizing props and removes Nextra classnames.
.gitignore Updates ignores for Vocs/Vite/Bun outputs and Cloudflare artifacts.
.github/workflows/README.md Updates workflow documentation for Bun/Vocs and adds Cloudflare deploy notes.
.github/workflows/preview.yaml Updates PR preview build to Bun and publishes out/public.
.github/workflows/lint.yaml Updates lint/link-check jobs to Bun install/run.
.github/workflows/deploy.yml Updates GitHub Pages deploy to Bun and publishes out/public.
.github/workflows/deploy-cloudflare.yml Adds optional Cloudflare Pages deploy workflow for migration testing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread vocs.config.ts
Comment thread src/vocs/layout.tsx
Comment thread src/vocs/root.css
Comment thread src/vocs/root.css
Comment thread src/vocs/root.css
Comment thread worker/index.js
Comment thread app/build/rpc/components/RPCMethod.tsx Outdated
Comment thread app/build/rpc/components/RPCMethod.tsx Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 42 out of 47 changed files in this pull request and generated 7 comments.

@@ -58,7 +54,7 @@ jobs:
rm -rrf "$TARGET_DIR"/*
Comment thread worker/index.js
Comment on lines +126 to +132
const pages = await getPages(env)
const contents = await Promise.all(
pages.map(async (pagePath) => ({
pagePath,
text: await readPageMarkdown(env, pagePath),
})),
)
Comment thread worker/index.js
Comment on lines +210 to +212
const url = new URL(request.url)
const isMcpPath = url.pathname === '/mcp' || url.pathname === '/api/mcp'

Comment on lines 24 to 35
useEffect(() => {
const observer = new MutationObserver(() => {
setIsDark(document.documentElement.classList.contains('dark'));
setIsDark(readIsDark());
});

observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class']
attributeFilter: ['data-vocs-theme', 'style']
});

return () => observer.disconnect();
}, []);
Comment on lines +20 to +21
<div className='rpc-param-modal' aria-labelledby='modal-title' role='dialog' aria-modal='true'>
<div className='rpc-param-modal__panel'>
Comment on lines +62 to +90
async function copyAppTree(currentDir = appDir) {
const entries = await readdir(currentDir, { withFileTypes: true })

for (const entry of entries) {
const sourcePath = path.join(currentDir, entry.name)
const relativePath = path.relative(appDir, sourcePath)

if (entry.isDirectory()) {
await copyAppTree(sourcePath)
continue
}

if (!entry.isFile() || ignoredFiles.has(entry.name)) continue

let targetRelativePath = relativePath
if (entry.name === 'page.mdx' || entry.name === '_page._mdx') {
targetRelativePath = path.join(path.dirname(relativePath), 'index.mdx')
}

const targetPath = path.join(generatedPagesDir, targetRelativePath)
await mkdir(path.dirname(targetPath), { recursive: true })
generatedFiles.add(toPosix(path.relative(generatedPagesDir, targetPath)))

if (entry.name.endsWith('.mdx')) {
const content = await readFile(sourcePath, 'utf8')
await writeFile(targetPath, withVocsMdxCompatibility(content))
} else {
await cp(sourcePath, targetPath)
}
Comment thread scripts/generate-llms.js
'> Official documentation for Celestia, the modular blockchain powering unstoppable apps with full-stack control.',
'',
'These docs are built with Next.js + Nextra and exported statically. Links below point to canonical markdown pages so tools and LLMs can ingest clean text.',
'These docs are built with Vocs and exported statically. Links below point to canonical markdown pages so tools and LLMs can ingest clean text.',
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.

3 participants