Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Head Start is a starter kit by [De Voorhoede](https://www.voorhoede.nl/en/) for

- **Framework:** [Astro](https://astro.build/) (v5, `output: 'server'` via Cloudflare adapter).
- **CMS:** [DatoCMS](https://www.datocms.com/) — content is fetched via GraphQL; schema is managed through migrations in [`config/datocms/migrations/`](./config/datocms/migrations/).
- **Hosting:** [Cloudflare Pages](https://pages.cloudflare.com/) (Workers runtime). Local preview uses `wrangler`.
- **Hosting:** [Cloudflare Workers](https://workers.cloudflare.com/) with static assets. Deployed via Workers Builds (`npm run cloudflare:build` + `wrangler deploy`). Local preview uses `wrangler dev`.
- **Philosophy:** no default JS framework, no default styling, progressively enhanced, fully accessible, highly performant. See [README › Philosophy](./README.md#philosophy) before suggesting new dependencies.

The repo is a small monorepo: the root is the Astro app; [`config/datocms/`](./config/datocms/) is an npm workspace for CMS-side tooling.
Expand Down Expand Up @@ -48,7 +48,8 @@ Run everything from the repo root:
| `npm install` | Install deps (also runs `husky` hooks install). |
| `npm run dev` | Start Astro dev server at <http://localhost:4323> plus GraphQL/icon/translation watchers in parallel. |
| `npm run build` | Runs `prep` (clean, download CMS data, generate types, build icon sprite) then `astro build`. |
| `npm run preview` | Serve the built `dist/` with `wrangler pages dev` (closest to production). |
| `npm run preview` | Serve the built `dist/` with `wrangler dev` (closest to production). |
| `npm run deploy` | Deploy to Cloudflare Workers with `wrangler deploy`. |
| `npm run lint` | Runs `astro check` + ESLint + `html-validate` over `dist/`. `lint:html` requires a build first. |
| `npm run test` / `npm run test:unit` | Vitest unit tests (`*.test.ts`). Depends on `prep`. |
| `npm run analyze` | Build with Sonda bundle analyzer (writes to `reports/`). |
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,13 @@
# Changelog

See [documentation on Upgrading](docs/upgrading.md#find-the-changes).

## Unreleased

### Changed

- Migrated hosting from Cloudflare Pages to Cloudflare Workers with static assets. Deployment now uses `wrangler deploy` via Cloudflare Workers Builds instead of the legacy Pages deployment pipeline.
- `npm run preview` now uses `wrangler dev` instead of `wrangler pages dev ./dist`.
- `npm run deploy` added as the explicit deploy command.
- Build environment variables updated: `CF_PAGES` / `CF_PAGES_BRANCH` / `CF_PAGES_URL` replaced by `WORKERS_CI` / `WORKERS_CI_BRANCH` / `WORKERS_CI_COMMIT_SHA`.
- Default production URL changed from `*.pages.dev` to `*.workers.dev` (override with a custom domain as before).
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ The site is created as lightweight progressively enhanced website connected to a

- [Astro](https://astro.build/) - web framework to structure this project. Astro is selected because it embraces web standards, is designed for performance, and supports all our favourite UI frameworks (React, Vue and Svelte).
- [DatoCMS](https://www.datocms.com/) - a headless CMS is connected to manage web content. DatoCMS is selected for its modular and structured content options, advanced image service, multi-language support and GraphQL API.
- [Cloudflare Pages](https://pages.cloudflare.com/) - is a JAMstack hosting platform. Cloudflare Pages is selected for its reliable CDN, zero cold-start workers, green hosting and affordable pricing.
- [Cloudflare Workers](https://workers.cloudflare.com/) - is a serverless hosting platform. Cloudflare Workers is selected for its reliable CDN, zero cold-start runtime, green hosting and affordable pricing.

```mermaid
%%{
Expand All @@ -52,7 +52,7 @@ flowchart LR


CMS[(DatoCMS)]
Hosting(Cloudflare Pages)
Hosting(Cloudflare Workers)
CMS -- publish --> Hosting

Repository -- git commit --> Hosting
Expand Down Expand Up @@ -94,7 +94,8 @@ All commands are run from the root of the project, from a terminal:
|:------------------------| :-----------------------------------------------
| `dev` | Starts local dev server at `localhost:4323` (head in T9)
| `build` | Build your production site to `./dist/`
| `preview` | Preview your build locally, before deploying
| `preview` | Preview your build locally with `wrangler dev`, before deploying
| `deploy` | Deploy to Cloudflare Workers with `wrangler deploy`
| `astro ...` | Run commands like `astro add` (see `astro -- --help`)
| `create` | Scaffold new Block, Component, API or Page route
| `analyze` | Analyze and visualise both client & server bundles
Expand Down
10 changes: 5 additions & 5 deletions astro.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ import { output } from './config/output';
import serviceWorker from './config/astro/service-worker-integration.ts';

const isAnalyseMode = process.env.ANALYZE === 'true';
const productionUrl = `https://${pkg.name}.pages.dev`; // overwrite if you have a custom domain
const productionUrl = `https://${pkg.name}.workers.dev`; // overwrite if you have a custom domain
const localhostPort = 4323; // 4323 is "head" in T9

export const siteUrl = process.env.CF_PAGES
? (process.env.CF_PAGES_BRANCH === 'main')
? productionUrl
: process.env.CF_PAGES_URL
// Workers Builds injects WORKERS_CI=1 and WORKERS_CI_BRANCH but has no per-deploy
// preview URL equivalent to CF_PAGES_URL, so non-main branches fall back to productionUrl.
export const siteUrl = process.env.WORKERS_CI
? productionUrl
: `http://localhost:${localhostPort}`;

// https://astro.build/config
Expand Down
2 changes: 1 addition & 1 deletion config/preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,5 @@ function getGitBranch() {
}

export const isPreview = previewBranches.includes(
process.env.CF_PAGES_BRANCH || getGitBranch(),
process.env.WORKERS_CI_BRANCH || getGitBranch(),
);
24 changes: 24 additions & 0 deletions docs/decision-log/2026-07-03-pages-to-workers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Cloudflare Pages to Workers migration

**Migrate hosting from Cloudflare Pages to Cloudflare Workers with static assets.**

- Date: 2026-07-03
- Decision Made By: [Marleen](https://github.com/marleendijkman)

## Decision

Migrate the project from Cloudflare Pages to Cloudflare Workers

## Why

Cloudflare has deprecated Cloudflare Pages and will turn to Cloudflare Workers.
The `@astrojs/cloudflare` adapter v13+ explicitly targets Workers only and drops Pages support.

## What changed
The below is in accordance with the [official migration guide](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/)
- `wrangler.toml` udpated with Workers-specific config: `main`, `assets` with `binding`, `nodejs_compat` flag.
- `public/.assetsignore` added so `_worker.js` and `_routes.json` are not served as static files.
- `npm run preview` now uses `wrangler dev` (instead of `wrangler pages dev ./dist`).
- `npm run deploy` added as the deploy command.
- `CF_PAGES` / `CF_PAGES_BRANCH` / `CF_PAGES_URL` env vars replaced by the Workers Builds equivalents: `WORKERS_CI`, `WORKERS_CI_BRANCH`, `WORKERS_CI_COMMIT_SHA`.
- `siteUrl` in `astro.config.ts` now resolves to `productionUrl` on any Workers Builds run (Workers Builds has no per-deploy branch preview URL env var equivalent to `CF_PAGES_URL`).
6 changes: 3 additions & 3 deletions env.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ declare global {
namespace NodeJS {
interface ProcessEnv {
CI?: string;
CF_PAGES?: string;
CF_PAGES_BRANCH?: string;
CF_PAGES_URL?: string;
WORKERS_CI?: string;
WORKERS_CI_BRANCH?: string;
WORKERS_CI_COMMIT_SHA?: string;
DATOCMS_API_TOKEN: string;
DATOCMS_READONLY_API_TOKEN: string;
HEAD_START_PREVIEW?: string;
Expand Down
Loading
Loading