Cloudflare Pages Deployment Guide

This guide explains how to deploy the Adblock Compiler UI to Cloudflare Pages.

Overview

This project uses Cloudflare Workers for the main API/compiler service and Cloudflare Pages for hosting the static UI files in the public/ directory.

Important: Do NOT use deno deploy

⚠️ Common Mistake: This project is NOT deployed using deno deploy. While this is a Deno-based project, deployment to Cloudflare uses Wrangler, not Deno Deploy.

Why not Deno Deploy?

  • This project targets Cloudflare Workers runtime, not Deno Deploy
  • The worker uses Cloudflare-specific bindings (KV, R2, D1, etc.)
  • The deployment is managed through Wrangler CLI

Deployment Options

The repository includes automated CI/CD that deploys to Cloudflare Workers and Pages automatically.

See .github/workflows/ci.yml for the deployment configuration.

Requirements:

  • Set repository secrets:
    • CLOUDFLARE_API_TOKEN
    • CLOUDFLARE_ACCOUNT_ID
  • Enable deployment by setting repository variable:
    • ENABLE_CLOUDFLARE_DEPLOY=true

Option 2: Manual Deployment

Workers Deployment

# Install dependencies
npm install

# Deploy worker
deno task wrangler:deploy
# or
wrangler deploy

Angular SPA Deployment (Frontend)

The Angular frontend is deployed as part of the Cloudflare Workers bundle via the Worker's ASSETS binding, not as a standalone Cloudflare Pages project. (The "Cloudflare Pages" sections below cover only the legacy public/ static UI.) The build process requires a postbuild step because Angular's SSR builder with RenderMode.Client emits index.csr.html instead of index.html:

cd frontend

# npm run build automatically runs the postbuild lifecycle hook:
#   1. ng build  → emits dist/frontend/browser/index.csr.html
#   2. postbuild → copies index.csr.html to index.html
npm run build

# Deploy the Worker (which serves the Angular SPA via ASSETS binding)
deno task wrangler:deploy

The postbuild step is handled by frontend/scripts/postbuild.js. If you skip the postbuild, the Cloudflare Worker ASSETS binding falls back to index.csr.html, but the recommended path is always to run npm run build (not ng build directly).

SPA Routing (Worker): The Cloudflare Worker already handles SPA fallback — extensionless paths not matched by API routes are served the Angular shell (index.html) via the ASSETS binding. SPA Routing (Pages-only): If you deploy the Angular dist/ output directly to Cloudflare Pages instead of serving it via the Worker ASSETS binding, you can use a _redirects file for SPA routing. In that setup, frontend/src/_redirects should contain /* /index.html 200, and this file is copied into the browser output root during the Angular build via angular.json's assets configuration.

Pages Deployment (Legacy static UI — Retired)

⚠️ Retired: The adblock-compiler-ui Cloudflare Pages project has been retired. The Angular SPA is now served exclusively via the Worker's [assets] binding at https://adblock-compiler.jayson-knight.workers.dev. The CI steps that deployed to Pages have been removed.

The command below is kept for historical reference only and should not be used:

# RETIRED — do not use
# wrangler pages deploy public --project-name=adblock-compiler-ui

Cloudflare Pages Dashboard Configuration

If you're setting up Cloudflare Pages through the dashboard, use these settings:

Build Configuration

SettingValue
Framework presetNone
Build commandnpm install
Build output directorypublic
Root directory(leave empty)

Environment Variables

VariableValue
NODE_VERSION22

⚠️ Critical: Deploy Command

DO NOT set a deploy command to deno deploy. This will cause errors because:

  1. Deno is not installed in the Cloudflare Pages build environment by default
  2. This project uses Wrangler for deployment, not Deno Deploy
  3. The static files in public/ don't require any build step

Correct configuration:

  • Deploy command: Leave empty or use echo "No deploy command needed"
  • The public/ directory contains pre-built static files that are served directly

Common Errors

Error: /bin/sh: 1: deno: not found

Symptom:

Executing user deploy command: deno deploy
/bin/sh: 1: deno: not found
Failed: error occurred while running deploy command

Solution: Remove or change the deploy command in Cloudflare Pages dashboard settings:

  1. Go to Pages project settings
  2. Navigate to "Builds & deployments"
  3. Under "Build configuration", clear the "Deploy command" field
  4. Save changes

Error: Build fails with missing dependencies

Solution: Ensure the build command is set to npm install (not npm run build or other commands).

Architecture

flowchart TB
    PAGES["Cloudflare Pages"]
    subgraph STATIC["Static Files (public/)"]
        I["index.html (Admin Dashboard)"]
        C["compiler.html (Compiler UI)"]
        T["test.html (API Tester)"]
    end
    WORKERS["Cloudflare Workers"]
    subgraph WORKER_INNER["Worker (worker/worker.ts)"]
        API["API endpoints"]
        SVC["Compiler service"]
        BINDINGS["KV, R2, D1 bindings"]
    end

    PAGES --> I
    PAGES --> C
    PAGES --> T
    PAGES -->|calls| WORKERS
    WORKERS --> API
    WORKERS --> SVC
    WORKERS --> BINDINGS

Verification

After deployment, verify:

  1. Pages URL: https://YOUR-PROJECT.pages.dev

    • Should show the admin dashboard
    • Should load without errors
  2. Worker URL: https://adblock-compiler.YOUR-SUBDOMAIN.workers.dev

    • API endpoints should respond
    • /api should return API documentation
  3. Integration: The Pages UI should successfully call the Worker API

Troubleshooting

Pages deployment works but Worker calls fail

Cause: CORS issues or incorrect Worker URL in UI

Solution:

  1. Check that the Worker URL in the UI matches your deployed Worker
  2. Ensure CORS is configured correctly in worker/worker.ts
  3. Verify the Worker is deployed and accessible

UI shows but API calls return 404

Cause: Worker not deployed or incorrect API endpoint

Solution:

  1. Deploy the Worker: wrangler deploy
  2. Update the API endpoint URL in the UI files if needed
  3. Check Worker logs: wrangler tail

Support

For issues related to deployment, please:

  1. Check this documentation first
  2. Review the Troubleshooting Guide
  3. Open an issue on GitHub with deployment logs