Deconstructing this website

This is how this website is built. It runs on Cloudflare, a network of data centres around the world, and every claim on this page links to the file that proves it.

Four layers, on Cloudflare

layer 1 · Cloudflare

The network

How a visit reaches this website.

When you type the address, Cloudflare's DNS answers. The zone is signed with DNSSEC, a signature that lets anyone check the answer was not altered on the way. The connection is encrypted with TLS 1.3 at the least, and in browsers that support it not even the site's name travels in the clear. On the other side there is no server of our own: a Worker answers, a program Cloudflare runs in the data centre closest to the visitor.

visitoropens a pageDNSSECsigned zoneTLS 1.3Encrypted Client Hello
Custom Domainsautomatic certificate
Workersthe origin
Cloudflare dashboard: minimum TLS version 1.3, TLS 1.3 on and Encrypted Client Hello on
The zone's Cloudflare dashboard: TLS 1.3 as the minimum, and Encrypted Client Hello on.
Detail and proof 3 rows
  1. 1.1

    DNS is authoritative on Cloudflare, and the zone is signed with DNSSEC.

    no file: checked in the zone's APIDNS full setup · DNSSEC
  2. 1.2

    TLS 1.3 is the minimum version the zone accepts. Encrypted Client Hello is on. Clients that support it also get the post-quantum key agreement Cloudflare offers by default.

    no file: checked in the zone's APIMinimum TLS · Encrypted Client Hello · post-quantum
  3. 1.3

    Always Use HTTPS redirects plain HTTP at the edge. The app sends HSTS with a one-year max-age, includeSubDomains and preload.

layer 2 · Cloudflare

The cache

Which pages are kept ready-made, and when they are cleared.

In front of the Worker sits Cloudflare's cache, which keeps copies of pages in each data centre. If the page you ask for is already stored, it is delivered without running the Worker. Only pages that ask for it are stored, and publishing a change from the content management system (the CMS) clears, by tag, that page and every page that lists it.

Detail and proof 5 rows
  1. 2.1

    Workers Cache sits in front of the Worker and is tiered by default: a hit does not run the Worker.

  2. 2.2

    A rendered page is cached at the edge only if it opts in. A response that declares no caching of its own is sent no-store.

  3. 2.3

    Publishing an entry purges, by cache tag, its own pages and the pages that list it. Menus and settings are not purged; they expire within the hour.

  4. 2.4

    Build output under /_astro/ is content-hashed and served with a one-year, immutable max-age.

  5. 2.5

    Resized images are kept in the Cache API.

    no file: in the @astrojs/cloudflare dependencyCache API

layer 3 · Cloudflare

Compute

Where the code that builds each page runs.

The whole site is produced by a single Worker with Astro, a framework that assembles each page at the moment it is requested. Files that never change, such as styles, scripts and images, are served directly, without running any code. There is no server behind it, and before answering the Worker adds seven security headers to every page.

Detail and proof 5 rows
  1. 3.1

    One Worker renders the pages on demand with Astro (SSR). The built files are served as Workers Static Assets without running it. There is no server behind the Worker.

  2. 3.2

    The team that makes Astro has worked at Cloudflare since January 2026. Astro remains MIT-licensed and openly governed.

    no file: per the announcementannouncement
  3. 3.3

    One middleware stamps 7 security headers on every page the Worker renders. The CSP admits one outside script and no other: the visit counter from Cloudflare.

  4. 3.4

    The Worker knows the visitor's city and which Cloudflare data centre answered (request.cf). The edge-security opening shows them.

  5. 3.5

    CMS plugins can run in their own Dynamic Worker, with no network of their own and fixed CPU, subrequest and time limits. Everything they do passes through a bridge that checks the capabilities each one declares.

layer 4 · Cloudflare

Data

Where each thing is kept.

The texts and their history live in D1, Cloudflare's SQLite database. Editors' sessions are kept in Workers KV, a key-value store; Images fits the photographs that are resized to their slot and turns them into WebP; and R2, the file storage, is ready for whatever is uploaded through the CMS. The preview and production share none of the four.

Cloudflare dashboard: the production Worker's bindings, D1, Images, Dynamic Workers, R2 and KV
The Worker bindings in the Cloudflare dashboard. The sixth, ASSETS, is added by the Astro adapter at build time.
Detail and proof 5 rows
  1. 4.1

    D1 (SQLite) holds the content, its revisions and the settings. Each request opens a D1 session.

  2. 4.2

    Workers KV holds the editors' sessions.

  3. 4.3

    The photographs the page resizes go through the Images binding, which fits them to their slot and converts them to WebP. Everything else is served as it is in the repository.

  4. 4.4

    R2 is wired as the CMS media store. Today every image on the site ships with the code.

  5. 4.5

    Preview and production each have their own D1, Workers KV and R2.

Inside the Worker

inside the Worker

Presentation

How what you see is drawn.

The interface is built with Astro and a single stylesheet. Fonts, scripts and images come from the site itself; the one thing fetched from outside is the visit counter from Cloudflare. The openings of each section pair restored photographs with a drawing animated in the browser.

The edge-security opening at rest: the Cabo Peñas lighthouse with its outline in orange and the radar sweep
Cabo Peñas · Einaz80 · CC BY-SA 4.0
The greenfield development opening at rest: the Guggenheim Museum Bilbao seen from the estuary
Guggenheim · Sergio S.C · CC BY-SA 2.0
1outside provider the browser calls: Cloudflare
one stylesheet for everything
Detail and proof 7 rows
  1. 5.1

    One stylesheet declares every colour, radius and shadow, the column width and the spacing scale. CI rejects those values written anywhere else, except in marked blocks that imitate another product's interface.

  2. 5.2

    Outside the site, the browser calls Cloudflare and nobody else: it downloads the Web Analytics script and sends it its measurements, with no cookies and identifying no one. Fonts, images and every other script are the site's own. Zaraz, Cloudflare's tag manager, loads on every page from this same domain and receives the answer you give in the cookie notice. If you accept analytics, it sends the visit to Google Analytics 4 from Cloudflare's servers: even then the browser never calls Google. If you decline, Google Analytics 4 never runs.

  3. 5.3

    The fonts live in the repository, so building the site does not depend on Google Fonts. Cloudflare Fonts does not apply: it only rewrites links to Google Fonts, and there are none here.

  4. 5.4

    Each vertical opens with a Wikimedia Commons photograph, restored and partly redrawn, and a layer drawn live in the browser. The layer is placed against the measured text, and its clock stops at eight seconds: nothing loops.

  5. 5.5

    The photographs were restored locally with SeedVR2. FLUX.2 [dev] (Black Forest Labs) on Workers AI removed objects, extended frames and redrew from the photographs. Every prompt is in the repository.

    docs/design/hero-rotativo/photo_restore.py[FLUX.2 [dev]](https://developers.cloudflare.com/workers-ai/models/flux-2-dev/)
  6. 5.6

    The photographs are CC BY-SA, and the site credits them with the changes stated.

  7. 5.7

    The cookie notice is the site's own. It is a card in the bottom-left corner, and the page keeps working behind it while you decide. Accept and Reject are two identical buttons, side by side. The notice has no close button and waits for your answer. “Cookie preferences”, in the footer, opens it again. Zaraz's own window is off because it blocks the whole page, and the cookie guide of Spain's data protection authority (AEPD) asks for less. It asks for Reject at the same level as Accept, a notice that stays until you answer, and withdrawal as easy as consent. Only your click passes the answer to Zaraz, through its consent API. Google Analytics 4 is not needed to count visits, since Web Analytics already does. It is here because this site is also a lab.

inside the Worker

The CMS: EmDash

Where the content is edited.

The site's CMS is EmDash, Cloudflare's open-source content management system, and it runs inside the same Worker that serves the pages. Its admin edits pages, services, menus and every interface label, in Spanish and English. On publishing, a plugin kept in the repository clears what changed from the cache.

The EmDash editor with the Deconstructing this website page open
The EmDash editor, in the site's admin.
Detail and proof 10 rows
  1. 6.1

    EmDash, the open-source (MIT) CMS that Cloudflare announced in April 2026, runs inside the same Worker.

  2. 6.2

    Cloudflare runs its own blog on EmDash.

    no file: per its blogthe Cloudflare blog
  3. 6.3

    Five content types: pages, services, members, references and partners, with blog posts ready and empty. Pages and services have drafts; those two and members keep revisions. Bodies are Portable Text.

  4. 6.4

    Two languages: pages, services and members are published in pairs linked by translationOf.

  5. 6.5

    Menus, widget areas, site settings and taxonomies come from the CMS. Every interface label lives in a widget, not in a template.

  6. 6.6

    Search comes from EmDash, on SQLite FTS5 with bm25 ranking.

    no file: in EmDash, migration 064
  7. 6.7

    The admin admits editors by passkey (WebAuthn) only: there is no password to store or leak.

    no file: answered by /_emdash/api/auth/modeauthentication
  8. 6.8

    EmDash is also an OAuth authorization server (the OAuth 2.1 profile: code + PKCE, dynamic client registration). So an AI agent can work on the content through its MCP server, with a token an editor grants.

    no file: answered by the admin's endpointsMCP server · AI tools
  9. 6.9

    The emdash command line signs in with the OAuth device flow (RFC 8628).

    no file: answered by /_emdash/.well-known/authMCP server
  10. 6.10

    A plugin kept in the repository purges the cache on publish. It declares content:read, because without it EmDash skips its hooks.

Across the layers, from the workshop

across the layers · from the workshop

Delivery

How a change reaches production.

The code lives in a GitHub repository. Every change comes in as a reviewable proposal, a pull request, and goes through 27 steps of automatic checks (the continuous integration, or CI) against a local copy of the site. If they all pass, the preview deploys itself with wrangler, Cloudflare's deployment tool. Production is deployed by hand, and a guard refuses to overwrite a database that already holds content.

A deploy-preview run on GitHub Actions: deploy and verify green
The preview deploys itself once the gates pass, on GitHub Actions.
Detail and proof 5 rows
  1. 7.1

    The working repository is public, with all its commits.

  2. 7.2

    Every change that can reach a page passes 27 steps that can fail. A test derives that number from the workflow.

  3. 7.3

    The gates run the site locally on workerd, the open-source runtime behind Workers, through wrangler dev. If wrangler itself crashes, the stack restarts once and the summary says so.

  4. 7.4

    When the gates pass on main, the preview deploys itself with wrangler-action. It waits for the D1 migrations, reseeds after rehearsing the SQL on a throwaway database, and runs a smoke battery.

  5. 7.5

    Production deploys only when the founder starts it by hand, and a guard refuses to overwrite a database that holds content.

across the layers · from the workshop

Content

Where every text is written.

Every word on the site lives in one file in the repository, seed/seed.json, in Spanish and English. On every change, the CI builds the site and fills an empty database from that file, so the whole site can be rebuilt from scratch at any time.

The repository's seed folder on GitHub, with seed.json and the content folder
The seed/ folder of the public repository.
Detail and proof 4 rows
  1. 8.1

    Every sentence the site renders lives in one versioned file, seed/seed.json. The service pages are written in Markdown, and the CMS converts them into that file. A test keeps the two word for word, and a CI gate rejects copy typed into a template.

  2. 8.2

    On every change that can reach a page, CI builds the site and fills an empty database from that file, twelve times in parallel.

  3. 8.3

    Service slugs are translated, so the other language's URL is never guessed. hreflang and the language switcher read the same resolved value.

  4. 8.4

    The sitemap is generated from the CMS collections.

across the layers · on every change

Quality

What is checked before anything is published.

The accessibility, design, text and language checks first plant the defect they look for and pass only once they find it. Lighthouse, Google's tool that scores performance and accessibility, measures nine pages; the text of 30 routes is frozen; and every opening is tried in Safari's and Chrome's engines. AI agents write most of the code, and the founder merges every change.

27steps that can fail
30routes with frozen text
≥95performance
100accessibility
100best practices
100SEO
Lighthouse on 9 pages, in CI against a local copy, on 2026-10-16
A quality-gates run on GitHub Actions with every job green
The gates for a change on main, all green, on 2026-10-16.
Detail and proof 7 rows
  1. 9.1

    The accessibility, engine, design, layout, copy, language and naming checks plant the defect they hunt, and must catch it before they report green.

  2. 9.2

    Lighthouse in CI, against a local copy, takes the median of 3 runs on 9 pages: performance ≥95; accessibility, best practices and SEO, 100. All nine met it on 2026-10-16.

  3. 9.3

    Accessibility: axe (WCAG 2.2 A+AA) and a keyboard pass on every route of the site, plus reflow at 320 px. Where text sits on a photograph, contrast is measured on the rendered pixels.

  4. 9.4

    Each opening is checked mid-animation and at rest, in Safari's engine (iPhone and desktop profiles) and Chrome's (Pixel 7), with reduced motion too.

  5. 9.5

    The rendered text of 30 routes is frozen. Changing a word fails until the new text is deliberately re-captured, so the change shows in the pull request's diff.

  6. 9.6

    AI agents write most of the code under written rules, and the founder merges every pull request.

    no file: shown by the merge historythe repository
  7. 9.7

    Every push is scanned for secrets, and a guard rejects any client name not published under References.

The workshop, open

If someone tells you how they work and cannot show you the workshop, be wary. This is ours: code, content, checks and deployments.

See the repository

Let's talk, engineer to engineer.

Bring the problem as it is. You'll hear back from the person who'll write the code.

Tell us about your project