Agent-readable docs index: /llms.txt. Full docs in one file: /llms-full.txt. Download /docs.zip to grep all markdown files locally.

Cloudflare Workers

Holocron can be deployed to Cloudflare Workers for edge-rendered docs with global distribution.

Setup

Install wrangler and the Cloudflare Vite plugin:
pnpm add -D wrangler @cloudflare/vite-plugin
Add the Cloudflare plugin after Holocron in vite.config.ts:
import { cloudflare } from '@cloudflare/vite-plugin' import { holocron } from '@holocron.so/vite' import { defineConfig } from 'vite' export default defineConfig({ plugins: [ holocron(), cloudflare({ viteEnvironment: { name: 'rsc', childEnvironments: ['ssr'], }, }), ], })
Create a wrangler.json or wrangler.jsonc:
{ "name": "my-docs", "main": "spiceflow/cloudflare-entrypoint", "compatibility_date": "2026-04-13", "compatibility_flags": ["nodejs_compat"] }

Build and deploy

npx vite build npx wrangler deploy

Preview and production environments

Wrangler named environments inherit top-level routes. If production owns a custom domain and preview should use workers.dev, preview must explicitly set "routes": []. Omitting the property can reassign the production domain to the preview Worker during wrangler deploy --env preview.
{ "name": "my-docs", "routes": [ { "pattern": "docs.example.com", "custom_domain": true } ], "env": { "preview": { "name": "my-docs-preview", "routes": [] } } }
Set CLOUDFLARE_ENV while Vite builds so the Cloudflare plugin flattens the matching environment into dist/rsc/wrangler.json:
{ "scripts": { "deploy": "CLOUDFLARE_ENV=preview vite build && wrangler deploy --env preview", "deploy:prod": "vite build && wrangler deploy" } }
Run package scripts explicitly:
pnpm run deploy pnpm run deploy:prod
pnpm deploy is pnpm's built-in deployment command, not a reliable way to run the package's "deploy" script. Treat Wrangler warnings about inherited routes or custom-domain reassignment as deployment blockers.

Serving docs under a subpath

Set base in vite.config.ts to mount the whole site under a path prefix, for example when the docs live at example.com/docs behind a route:
export default defineConfig({ base: '/docs', plugins: [holocron(), cloudflare({ /* ... */ })], })
Holocron nests the client build output under a folder matching the base, so Cloudflare serves /docs/assets/app.js from dist/client/docs/assets/app.js:
vite.config.ts build output request ┌───────────────────┐ ┌───────────────────────────┐ ┌────────────────────────┐ │ base: '/docs' │───────>│ dist/client/ │ │ GET /docs/assets/app.js│ │ │ │ .assetsignore │ └───────────┬────────────┘ │ HTML references │ │ docs/assets/app.js <───┼───────────────────┘ │ /docs/assets/* │ │ docs/icons/logo.svg │ served by the CDN, └───────────────────┘ └───────────────────────────┘ no Worker invocation

Custom entry with Workers

If you use a custom entry, your Spiceflow app runs as the Worker entry point. You can add Cloudflare-specific bindings (KV, D1, AI) alongside your docs.

Example project

See the example-cloudflare/ directory in the Holocron repo for a minimal Cloudflare Workers deployment.
Cloudflare's Asset Worker looks paths up in the uploaded directory tree and never strips Vite's base, so this nesting is what makes subpath hosting work. It happens automatically; no ASSETS binding or extra config needed.