Cloudflare Pages, Workers, Access And CDN

A first-principles explanation of what happens when a protected static site is deployed to Cloudflare Pages, and how that differs from a Pages deployment with _worker.js.

1 Visitor Browser

The user asks for a page such as /pages/flowchart.html.

2 Cloudflare Edge

The request reaches Cloudflare's global network first, not an origin server you manage.[1]

3 Cloudflare Access

Access checks whether the visitor has a valid email OTP session before content is returned.

4 Cloudflare Pages

Pages maps the URL to the deployed static asset bundle for the Pages project.

5 Static Response

The HTML, CSS, or JS file is served from Cloudflare's edge/CDN network.[2][3]

Cloudflare Pages

Pages is the static site hosting product. You upload a folder like:

dist/
  index.html
  pages/
  assets/css/styles.css
  assets/js/app.js

Pages stores those files as deployment assets, gives the project a pages.dev hostname, and serves matching files from Cloudflare's network.[1][2]

Cloudflare Access

Access is the policy layer in front of the site. It can require email OTP validation before the Pages asset is returned.[4]

Access does not store your site files. It decides whether a request is allowed to proceed to the protected application.

CDN / Edge Serving

You do not separately tell Pages to use a CDN. Cloudflare Pages is already edge static hosting.[1][2]

For the pages-only deployment, static files are served from Cloudflare's edge/CDN after Access allows the request.[3]

Browser
  -> Cloudflare edge
  -> Access validates email session
  -> Pages serves static file from deployment assets
  -> Browser

Cloudflare Workers

Workers are edge compute: JavaScript/TypeScript that runs on a request and returns a response.[5]

A Worker can read headers, call D1/KV/R2/APIs, rewrite requests, generate responses, or wrap static asset serving.[6]

export default {
  async fetch(request, env) {
    return new Response("hello")
  }
}

Pages Is More Than CDN

A CDN is the delivery layer: it puts assets close to visitors and returns them quickly.[3] Cloudflare Pages is the static site hosting and deployment product built on Cloudflare's edge network.[1][2]

Cloudflare Pages
  = deploy/build product
  + static asset storage/versioning
  + pages.dev/custom domain routing
  + preview/production deployments
  + optional Functions/_worker.js
  + edge/CDN asset delivery

The Clean Mental Model

For static HTML, CSS, and JavaScript, Pages can feel like CDN-backed static hosting. The difference is that Pages also decides which deployment is live, how routes map to files, which branch gets a preview URL, and whether a Pages-attached Worker should run.

CDN     = delivery layer
Pages   = site hosting and deployment layer
Worker  = optional compute layer
Access  = optional gate layer

Pages Only

  • No _worker.js.
  • No Pages Function.
  • No D1 binding.
  • Pages serves static files directly after Access.

Pages + _worker.js

  • Pages still owns the static files and hostname.
  • _worker.js runs before returning the file.
  • The Worker can call env.ASSETS.fetch(request).[6]
  • Useful for logging Access emails to D1.

What Pages Does Then

  • Stores deployment assets.
  • Owns the pages.dev project.
  • Provides env.ASSETS to Pages Functions.[6]
  • Deploys static files and Functions together.

Why _worker.js Does Not Appear As A Separate Worker

A root _worker.js file makes Cloudflare Pages run your request handler on the Workers runtime, but it is attached to the Pages deployment rather than created as a separate standalone Worker service in the Workers dashboard.[5][6]

That is why the code uses the familiar fetch(request, env, ctx) API, but you still review it under the Pages project deployment. Pages owns the hostname and static assets; the attached runtime is the programmable layer for that Pages site.

What Happens In The Request Path

Browser
  -> Cloudflare Access validates email session
  -> Pages project receives allowed request
  -> _worker.js fetch handler runs
  -> Worker writes D1 access log if needed
  -> Worker returns env.ASSETS.fetch(request)
  -> Pages asset response reaches browser

Without _worker.js, Access can still protect the Pages site, and Pages can still serve the static files. The missing piece is trusted server-side logging because static browser JavaScript should not be trusted as the source of access records.

Deployment Request Handling Can Save Email Access Logs?
only_pages Access validates email, then Pages serves static files directly from deployment assets at the edge.[1][2] No. Static browser code should not be trusted to write access records, and there is no edge function to write to D1.
Pages + _worker.js Access validates email, Pages invokes the Worker, the Worker fetches the static asset through env.ASSETS, writes to D1, then returns the response.[6] Yes. The Worker can read the trusted Access email header and write a row to D1 before returning the page.
Memory Line

Pages is the shelf of static files on Cloudflare's edge. Access is the gate before the shelf. A Worker is optional code at the desk that can inspect, log, modify, or generate responses.[1][4][5]

Pages already uses Cloudflare CDN

References

  1. Cloudflare Pages overview: describes Pages projects as deployed to the Cloudflare global network.
  2. Cloudflare Pages limits - Files: states that Pages uploads each file on the site to Cloudflare's globally distributed network for low-latency delivery.
  3. Cloudflare Learning Center: What is a CDN?: explains that a CDN is a geographically distributed group of servers that delivers assets such as HTML pages, JavaScript files, stylesheets, images, and videos close to users.
  4. Cloudflare Access self-hosted applications: documents Access as the policy layer used to protect self-hosted applications.
  5. Cloudflare Workers overview: describes Workers as serverless code running on Cloudflare's global network.
  6. Cloudflare Workers static assets: documents static asset serving with Workers and the env.ASSETS.fetch() pattern.