Pages serves files. A Worker runs code. This is the building block behind every AI app in this series.
In Tutorial 1 you deployed a static HTML file with Cloudflare Pages. That works great for a page that never changes. But what if you want your site to respond differently depending on who’s visiting, what they typed, or what time it is? For that you need code that runs — not just a file that sits there.
That’s what a Worker is: a small program that runs every time someone visits your site, and decides what to send back.
| Pages | Worker | |
|---|---|---|
| What it serves | Static files (HTML, CSS, images) | Code that generates a response |
| Can it think? | No — same file every time | Yes — can react, calculate, call AI |
| Good for | Simple sites, blogs, brochures | Chat apps, APIs, anything dynamic |
💡 Why this matters: Every AI chat app in this series — PrivateAI, Qluv, DistantGhost — is a single Worker. No separate server, no database server, no hosting bill. Just one file of code running on Cloudflare’s network.
In your Cloudflare dashboard, click Workers & Pages in the left sidebar, then click Create.
Select Workers (not Pages), then pick the Hello World template. Give it a name — something like my-first-worker. Click Deploy.
🎉 Cloudflare just deployed a working Worker before you wrote a single line of code. You’ll get a URL like my-first-worker.<yoursubdomain>.workers.dev — open it and you’ll see “Hello World!”
Click Edit code to see what’s actually running. You’ll see something very close to this:
export default { async fetch(request) { return new Response("Hello World!"); } };
This is the entire pattern. Every single Worker you will ever build — including every AI chatbot in this series — starts with this exact shape. Let’s break it down:
💡 The mental model: Think of fetch(request) as a vending machine slot. Someone puts in a request (visits your URL), your code decides what happens, and a Response comes out. That’s the entire job of a Worker.
Right now it returns plain text. Let’s make it return an actual web page. Delete everything in the editor and replace it with this:
export default { async fetch(request) { const html = "<!DOCTYPE html><html><head><title>My Worker</title></head><body><h1>Built with a Cloudflare Worker</h1><p>This page is generated by code, not a static file.</p></body></html>"; return new Response(html, { headers: { "Content-Type": "text/html;charset=UTF-8" } }); } };
Click Save and deploy. Refresh your Worker’s URL — you now have a real web page, generated entirely by code.
⚠️ Important habit to build now: Notice the HTML is stored as a single text string in a variable called html, then handed to Response. This pattern — HTML as a string, not typed directly into the return statement — is what makes Workers manageable as your pages grow. Every Worker in this series follows this exact pattern.
Same process as Tutorial 1. In your Worker’s settings, go to the Domains tab, click Add Custom Domain, and enter your domain (or a subdomain like app.yourdomain.com if you want to keep your Pages site on the main domain).
💡 Subdomains are free and unlimited. You can have yourdomain.com on Pages and app.yourdomain.com on a Worker — completely separate, both on the same domain you already own.