Cloudflare Workers

A Worker is a small piece of code that runs at the edge — close to the visitor, with no server to manage. Use it for the dynamic bits a static site can't do itself: an API, a form handler, a redirect, an auth check.

Pages vs Workers — which one

Simple rule: Pages serves files; Workers run logic. A static site (HTML/CSS/JS) goes on Pages. The moment you need something to happen on the server — accept a form post, talk to a database, gate a page behind a login — that's a Worker. They live side by side and call each other.

Real example on this site: the contact form posts to a Worker (the "forms gateway") that checks spam, stores the message, and emails us — while the pages themselves are static on Pages.

Hello, Worker

A Worker is one fetch function that takes a request and returns a response:

export default {
  async fetch(request, env, ctx) {
    return new Response("Hello from the edge");
  }
};

Deploy with wrangler

wrangler is the Workers CLI — create, run locally, and deploy:

npm install -g wrangler
wrangler init my-worker     # scaffold
wrangler dev                # run locally at localhost
wrangler deploy             # publish to the edge

Config lives in wrangler.toml (the Worker's name, routes, and bindings). Tell your AI agent "deploy this Worker" and it runs these for you.

Routes — where it runs

Bind the Worker to a URL: a custom domain/subdomain (e.g. forms.flowsmith.online) or a route pattern. Until DNS is set it's also reachable at your-worker.your-subdomain.workers.dev.

# wrangler.toml
name = "forms"
main = "src/index.js"

[[routes]]
pattern = "forms.flowsmith.online"
custom_domain = true

Bindings — talk to storage & secrets

A Worker reaches other Cloudflare services through bindings declared in wrangler.toml and used as env.NAME — no connection strings, no keys in code:

BindingWhat it is
D1SQL database at the edge — env.DB.prepare(…).
KVKey-value store — fast reads, simple values.
R2Object storage (files, images) — S3-compatible.
Secretswrangler secret put NAME — API keys, tokens. Never in the repo.
Secrets go in with wrangler secret put (or the dashboard), never committed to git. The repo holds bindings and code; the secret values live only in Cloudflare.

Logs

Watch a deployed Worker live: wrangler tail streams its console + errors. Handy when a form post or API call misbehaves in production.

Serve the static side first — Cloudflare Pages → · A Worker in the wild — the forms gateway →