Skip to content

LiveOctober to November 2026

CookieConsentHQ

A cookie banner that blocks known trackers until visitors choose, records each choice, and keeps running after a site passes its plan's pageview limit.

I built CookieConsentHQ, a cookie consent platform for small businesses, online stores, SaaS sites and agencies. Its banner holds back known trackers until a visitor chooses, sets the Google Consent Mode v2 signals and records the choice. It keeps doing all three after a site passes its plan's monthly pageviews, because the banner is a static file cached on Cloudflare's edge and loading it runs no server code.

known-tracker URL patterns held until consent
30
built-in banner languages
7
banner loader gzipped (approximate), measured on a 6 November 2026 build
5 KB
database tables
27
database migrations
20
workspaces in the monorepo
11
test cases in the repository
721
commits from 19 October to 10 November 2026
241

Architecture

A Turborepo monorepo: one Next.js app and two Cloudflare Workers

My role: Product owner and developer. I set the requirements, reviewed and tested the work, and run the product, working with AI coding assistants.

  • apps/web

    The Next.js 16 app on Vercel: the marketing site, sign-in with Better Auth, the dashboard with its banner editor and live preview, and Paddle billing.

  • apps/edge

    A Cloudflare Worker for location lookups, consent records (through a queue with a dead-letter queue into Neon Postgres) and publishing banner files to R2 and KV.

  • apps/scanner

    A Cloudflare Worker that runs cookie scans in headless Chromium on Browser Rendering, one queued job at a time, behind an SSRF guard.

  • packages/runtime

    The banner: a small synchronous loader and an asynchronous UI in a Shadow DOM root, built with esbuild against a size budget.

  • packages/scanner-core

    Crawling, the built-in cookie database, AI classification of unknown cookies, issue checks and the SSRF rules.

  • packages/config-schema

    Zod schemas for the banner config, its texts in seven languages, region rules and the beacon protocol.

  • packages/db

    The Drizzle schema shared by the app and the Workers: 27 tables and 20 migrations.

  • integrations

    The Shopify app embed, the WordPress plugin and the Google Tag Manager template.

  • Next.js 16
  • React 19
  • TypeScript
  • Tailwind CSS v4
  • Turborepo
  • Better Auth
  • Drizzle ORM
  • Neon Postgres
  • PGlite
  • Zod
  • Cloudflare Workers
  • Cloudflare R2
  • Cloudflare KV
  • Cloudflare Queues
  • Cloudflare Browser Rendering
  • esbuild
  • Claude API
  • Paddle
  • Resend
  • PHP
  • Vitest
  • Playwright

The site

Eight screens from cookieconsenthq.com

The public site runs its own banner. The first picture is a first visit; the others were taken after choosing Reject all.

CookieConsentHQ home page with its own cookie banner open along the bottom, offering OK and Customize (opens the full-size screenshot in a new tab)
First visit: the site's own banner, with a sample consent log beside the headline.

Why it exists

A cookie banner that stays on past pageview limits

Cookie banner tools are usually priced by monthly pageviews, so what a tool does when a site passes its limit decides whether visitors still get a banner.

Here the plan decides only the price. Once a site passes its pageviews, the banner keeps showing, known trackers stay blocked and new consent records keep being stored, without overage fees. A Free site gets a note in the dashboard and a paid site an upgrade prompt.

The architecture is what makes that affordable. Each site's script is a static file in Cloudflare R2, served through the Cloudflare cache, so no Worker or server function runs when a page loads the banner. Publishing a change in the dashboard rebuilds that file, and visitors get it within about five minutes.

Everything else runs where it fits: the dashboard, sign-in and billing on Vercel, and small Workers for location lookups, consent records and scans, all sharing one Neon Postgres database.

Architecture

From page load to a stored consent record

Loading the banner

  • The first tag in the page's head loads the site's script from cdn.cookieconsenthq.com: the loader with the site's settings built in.
  • If the site uses region rules, one call to the edge Worker returns the visitor's country and region from Cloudflare.
  • The interface loads asynchronously and renders in a Shadow DOM root, so the host site's CSS cannot restyle it.

Recording a choice

  • The banner posts each choice to the edge Worker, which rate-limits it and puts it on a Cloudflare queue.
  • The queue consumer writes batches of up to 100 records to Neon Postgres. Each message is retried on its own, up to five times.
  • A record that keeps failing goes to a dead-letter queue, and the rest of its batch is still stored.

Publishing

  • Every banner config is checked against one shared Zod schema before it is saved.
  • The app builds the site's script, and the edge Worker writes it to R2 and the site's record to KV.
  • A release that changes the loader republishes live sites' scripts.

Scanning

A cookie scanner on Cloudflare Browser Rendering

Scans load a customer's pages in headless Chromium inside a Cloudflare Worker, so the scanner needs no servers of its own.

How a scan works

  • Each page is loaded as a first-time visitor, then the first few are loaded again after Accept all, to find cookies that only appear with consent.
  • Cookies are matched against a built-in cookie database and domain rules. Only names it does not know go to Claude Haiku, one domain per request, and no visitor data is sent.
  • Scheduled scans run monthly on Free, weekly on Starter and daily from Growth, which also emails when a new tracker appears.

SSRF guard

  • Every request the headless browser makes is held until the Worker checks it. Private, loopback, link-local and reserved ranges are refused.
  • Host names are resolved and every address checked. A failed lookup is refused too.
  • Top-level navigation must stay on the site's own host, with at most 20 redirects.

The free checker

  • /check loads one page and reports cookies set before consent, hardcoded tracker tags and Consent Mode v2 defaults, without sign-up.
  • A methodology page explains how each result is decided. It is versioned and dated: version 1, 10 November 2026.
  • A check holds back the banner's own consent and pageview pings, so it never adds a record to a site's log.

Data

What the consent log keeps about visitors

Stored identifiers

  • The edge removes the last octet of an IPv4 address and cuts IPv6 to a /48 before a record is stored.
  • User agents are stored as SHA-256 hashes instead of raw strings.
  • The site calls this data minimisation rather than anonymisation, because truncated identifiers can still count as personal data.

Where it runs

  • Consent records live in Neon Postgres in Frankfurt (AWS eu-central-1), and the app runs on Vercel functions in Frankfurt.
  • Customers sign in with emailed links or Google and keep no password with the service.
  • The internal admin sits behind Cloudflare Access, an email allowlist and an authenticator code, with an audit log.

Business

Billing, plans and integrations

Plans

  • Paddle checkout has been live since 20 October 2026, with Paddle as merchant of record and signed webhooks.
  • Five plans by monthly pageviews: Free to 25,000, Starter at $8 to 150,000, Growth at $18 to 750,000 and Business at $39 to 5 million.
  • Agency, at $79, covers 25 sites and 10 million pooled pageviews. A year costs ten months.

Integrations

  • The Shopify app is listed on the Shopify App Store. It installs as an app embed, without theme code, and passes each choice to Shopify's Customer Privacy API.
  • Any HTML site, Webflow, Wix and Squarespace take one script tag.
  • A Google Tag Manager template installs by importing its file.

Not there yet

  • The WordPress plugin was submitted to WordPress.org on 6 November 2026 and is in review.
  • The Tag Manager template is not yet in the Community Template Gallery.
  • IAB TCF and GPP are not supported.

Quality

Testing and the security review

Automated

  • 721 test cases in the repository: unit tests across the apps and packages, and Playwright browser tests for the banner.
  • A heavier playground suite on a separate CI machine: strict CSP, hostile CSS, single-page apps, document.write, failing APIs and blocked cookies.
  • It also runs the edge Worker in workerd against 2,000 fuzzed requests, a full WordPress install with the WP Consent API, and the whole dashboard journey.
  • It runs in desktop Chrome, Firefox and Safari plus Android and iPhone emulation, with automated axe accessibility checks.

Size budget

  • The build fails when the gzipped loader passes 5,250 bytes or the interface passes 15 KB.
  • On the 6 November 2026 build the loader was about 5 KB gzipped and the interface under 10 KB.

Security review

  • On 20 October 2026 an AI-assisted security scan of the whole repository found 17 issues, and fixes for them were committed the same day.

Growth

Technologies and skills used

Edge architecture
Static, cached banner delivery from Cloudflare R2 and KV, with Workers only for location, consent and publishing.
Queues and data
Cloudflare Queues with batching, per-message retries and a dead-letter queue, into Neon Postgres with Drizzle.
Browser runtime
A TypeScript banner in a Shadow DOM root, built with esbuild under a size budget the build enforces.
Privacy engineering
IP truncation and hashed user agents at the edge, consent records with CSV export and retention by plan.
Security
An SSRF guard on headless Chromium, emailed sign-in links, and an admin behind Cloudflare Access.
AI integration
Claude classifies only the cookie names the built-in database does not know, one domain per request.
Full-stack TypeScript
Next.js 16 and React 19 in a Turborepo monorepo of 11 workspaces, with Zod schemas shared by app and Workers.
Billing and integrations
Paddle checkout and webhooks, a Shopify app on the Customer Privacy API, a WordPress plugin and a Tag Manager template.