🥞PancakeJS

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 wrangler

Configure 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:deploy

Follow 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_SECRET

Custom Domain

Add Domain to Cloudflare

In your Cloudflare dashboard:

  1. Go to Workers & Pages
  2. Select your worker
  3. Click SettingsTriggers
  4. 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.dev

Verify 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:build

Memory 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: deploy

Secrets Setup

  1. Go to Cloudflare DashboardMy ProfileAPI Tokens
  2. Create a token with Edit Cloudflare Workers permission
  3. Add as CLOUDFLARE_API_TOKEN in GitHub repository secrets

Next Steps

Your PancakeJS app is now running on the edge! Consider these next steps:

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.

On this page