Deploy to Cloudflare
Deploy your PancakeJS application to Cloudflare Workers for lightning-fast, globally distributed performance. This guide covers everything from initial setup to production deployment.
Cloudflare Workers run at the edge in 300+ cities worldwide, giving your AI tools sub-50ms latency for users everywhere.
Prerequisites
Before you begin, ensure you have:
- A Cloudflare account (free tier works)
- Your PancakeJS project ready for deployment
- Node.js 18+ installed
Quick Deploy
For the fastest path to production:
Install Dependencies
pnpm add @opennextjs/cloudflare
pnpm add -D wranglerConfigure Wrangler
Create a wrangler.jsonc file in your project root:
{
"$schema": "node_modules/wrangler/config-schema.json",
"name": "my-pancake-app",
"compatibility_date": "2024-12-01",
"compatibility_flags": ["nodejs_compat"],
"main": ".open-next/worker.js",
"assets": {
"directory": ".open-next/assets",
"binding": "ASSETS"
}
}Update Package Scripts
Add these scripts to your package.json:
{
"scripts": {
"build": "universal-apps build",
"cf:build": "opennextjs-cloudflare build",
"cf:preview": "pnpm cf:build && wrangler dev",
"cf:deploy": "pnpm cf:build && wrangler deploy"
}
}Deploy
pnpm cf:deployFollow the prompts to authenticate with Cloudflare. Your app will be deployed to a .workers.dev subdomain.
Detailed Configuration
Environment Variables
Set environment variables in your Cloudflare dashboard or via wrangler.jsonc:
{
"name": "my-pancake-app",
"compatibility_date": "2024-12-01",
"compatibility_flags": ["nodejs_compat"],
"vars": {
"API_KEY": "your-api-key",
"ENVIRONMENT": "production"
}
}For secrets (sensitive values):
# Add secrets via CLI
wrangler secret put API_SECRETCustom Domain
Add Domain to Cloudflare
In your Cloudflare dashboard:
- Go to Workers & Pages
- Select your worker
- Click Settings → Triggers
- Click Add Custom Domain
Configure DNS
If your domain is on Cloudflare, it's automatic. Otherwise, add a CNAME record:
Type: CNAME
Name: api (or your subdomain)
Target: your-worker.your-subdomain.workers.devVerify SSL
Cloudflare automatically provisions SSL certificates. Your app will be available at https://api.yourdomain.com.
Widget Hosting
Widgets are static HTML files that can be served from the same worker:
{
"name": "my-pancake-app",
"compatibility_date": "2024-12-01",
"compatibility_flags": ["nodejs_compat"],
"assets": {
"directory": ".open-next/assets",
"binding": "ASSETS"
},
// Serve widgets from /widgets path
"routes": [
{ "pattern": "*/widgets/*", "zone_name": "yourdomain.com" }
]
}Production Configuration
Caching
Leverage Cloudflare's cache for better performance:
// In your tool handlers
app.tool(
{ name: 'getStaticData' },
async (input, ctx) => {
// Check cache first
const cache = caches.default;
const cacheKey = new Request(`https://cache/${input.id}`);
let response = await cache.match(cacheKey);
if (response) {
return JSON.parse(await response.text());
}
// Fetch fresh data
const data = await fetchData(input.id);
// Cache for 1 hour
await cache.put(cacheKey, new Response(JSON.stringify(data), {
headers: { 'Cache-Control': 'max-age=3600' }
}));
return data;
}
);Rate Limiting
Protect your endpoints with Cloudflare's rate limiting:
{
"name": "my-pancake-app",
"compatibility_date": "2024-12-01",
"compatibility_flags": ["nodejs_compat"],
"rules": [
{
"action": "rate_limit",
"expression": "http.request.uri.path contains \"/api/\"",
"ratelimit": {
"requests_per_period": 100,
"period": 60
}
}
]
}Analytics
Enable Workers Analytics for monitoring:
{
"name": "my-pancake-app",
"analytics_engine_datasets": [
{ "binding": "ANALYTICS" }
]
}Then in your code:
app.tool(
{ name: 'trackedTool' },
async (input, ctx) => {
// Log analytics
ctx.env.ANALYTICS.writeDataPoint({
blobs: [input.toolName],
doubles: [Date.now()],
});
// ... tool logic
}
);Troubleshooting
Build Errors
"Cannot find module" — Ensure all dependencies are listed in package.json and not just devDependencies.
# Verify dependencies
pnpm install --prod
pnpm cf:buildMemory Limits
Cloudflare Workers have memory limits. For large payloads:
// Stream large responses
app.tool(
{ name: 'largeData' },
async (input) => {
const stream = await getLargeDataStream();
return new Response(stream, {
headers: { 'Content-Type': 'application/json' }
});
}
);Cold Starts
Workers have minimal cold starts, but optimize further:
- Keep bundle size small
- Lazy-load heavy dependencies
- Use Cloudflare's Smart Placement for consistent routing
CI/CD Integration
GitHub Actions
# .github/workflows/deploy.yml
name: Deploy to Cloudflare
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 8
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
- run: pnpm install
- run: pnpm cf:build
- uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
command: deploySecrets Setup
- Go to Cloudflare Dashboard → My Profile → API Tokens
- Create a token with Edit Cloudflare Workers permission
- Add as
CLOUDFLARE_API_TOKENin GitHub repository secrets
Next Steps
Your PancakeJS app is now running on the edge! Consider these next steps:
- Set up custom domains for production
- Configure caching for frequently accessed data
- Add analytics for monitoring
- Explore Cloudflare KV for persistent storage
Other Deployment Options
While this guide covers Cloudflare, PancakeJS can be deployed anywhere:
- Vercel — Zero-config Next.js deployment
- AWS Lambda — Serverless with API Gateway
- Railway/Render — Simple container deployments
- Self-hosted — Any Node.js server
Check our deployment overview for more options.