A technical breakdown of a standalone, database-free cookie consent architecture with multi-site config, conditional script loading, and Google Consent Mode v2 — includes a build blueprint.
AI-Ready Blueprints, Optimization, Tools, Websites

Building a Multi-Site Cookie Consent System from Scratch

A technical breakdown of a standalone, database-free cookie consent architecture with multi-site config, conditional script loading, and Google Consent Mode v2 — includes a build blueprint.
Cookie Consent System

A config-driven, database-free architecture for handling consent across several sites without renting a CMP subscription for each one.

Most cookie consent tutorials online fall into one of two camps. Either they're generic — "add this banner plugin, configure a few settings" — without ever explaining what the banner actually needs to do underneath, or they're a sales page for a paid CMP subscription priced per domain, per month, forever. Neither helped when the actual requirement was: several sites, one shared codebase, no recurring third-party cost, and full visibility into exactly what data goes where.

What follows is the architecture I built to solve that — standalone PHP and JavaScript, no WordPress dependency, no database, one JSON configuration file per site.

Why standalone, not a WordPress plugin

A WordPress-specific plugin ties the consent system to WordPress's update cycle, hook system, and — critically — a single install. Running the same logic across several client sites, some WordPress and some not, meant the consent mechanism needed to live outside any single CMS's plugin architecture entirely. The trade-off is losing the WordPress admin's native UI conventions. What's gained is a system that works identically whether the site behind it is WordPress, a static PHP template, or something else altogether.

The shape of it

One loader script reads a JSON config and outputs the banner. One JavaScript file handles the interaction — toggles, cookie writing, conditional script loading. One admin panel, password-protected, edits the JSON. That's the entire system. No ORM, no migrations, no consent logs written to a database on every page view.

cookie-consent/
├── loader.php
├── config.json
├── configs/
│   ├── site-one.com.json
│   └── site-two.com.json
├── admin/
│   └── index.php
└── assets/
    ├── js/cookie-consent.js
    └── css/cookie-consent.css

Everything lives in one JSON file

Colors, banner copy in two languages, the list of cookie categories, analytics IDs, policy URLs — all of it sits in config.json, read fresh on every page load. Nothing about branding or legal text is hardcoded into PHP or JS. Cloning the system for a new site with different colors and a different Google Analytics ID means writing a new JSON file, not touching a single line of code.

{
  "primary_color": "#2c5f2d",
  "ga4_id": "G-XXXXXXXXXX",
  "cookie_list": [
    { "category": "necessary", "locked": true, "default": true },
    { "category": "analytics", "locked": false, "default": false }
  ]
}

One field in that config does more work than its size suggests: policy_version. Bump it whenever the cookie policy text or category list changes materially, and every visitor who already consented — even from months ago — sees the banner again on their next visit. Skip this step after a legal text update and you end up with a site that's technically non-compliant for anyone who consented under the old terms, silently.

Multi-site resolution

In single-site mode, there's one config.json and nothing else to resolve. Multi-site mode adds a configs/ folder, one JSON file per domain, and a small resolution step in the loader: strip www. from the current host, look for a matching filename, fall back to a clearly-labeled default if nothing matches.

I'd argue the fallback behavior matters more than it first appears. Serving generic consent text on a domain nobody configured yet is worse than showing nothing — it implies a review that never happened. My preference is to fail loud in the admin panel rather than fail silent on the front end.

Conditional script loading — the actual point of the whole system

A consent banner that shows a nice UI but still loads Google Analytics unconditionally in the page head isn't a consent system. It's decoration. Every tracking script needs to be wrapped in a loader function, called only from inside the branch where that category was actually accepted.

function loadGA4(measurementId) {
    if (!measurementId) return;
    window.dataLayer = window.dataLayer || [];
    function gtag(){ dataLayer.push(arguments); }
    gtag('js', new Date());
    gtag('config', measurementId);
    var script = document.createElement('script');
    script.src = 'https://www.googletagmanager.com/gtag/js?id=' + measurementId;
    script.async = true;
    document.head.appendChild(script);
}

Adding a second tracking pixel later — Meta, LinkedIn, whatever comes next — follows the identical pattern: a new loader function, called from the same acceptance branch, gated behind its own category if it warrants a separate one. Nothing about the core architecture changes to accommodate a new vendor script.

Consent Mode v2, and why the order of operations matters

Google's Consent Mode v2 expects a default state set before any consent decision exists, then an update once the visitor chooses:

gtag('consent', 'default', {
    'ad_storage': 'denied',
    'ad_user_data': 'denied',
    'ad_personalization': 'denied',
    'analytics_storage': 'denied'
});

Once a choice is made, an update call adjusts the relevant signals rather than triggering a page reload or re-injecting scripts from scratch:

gtag('consent', 'update', {
    'analytics_storage': acceptedAnalytics ? 'granted' : 'denied'
});

This default-then-update sequence is what allows Google Analytics to run in a limited, cookieless mode even before consent exists, rather than an all-or-nothing switch. I'd flag one thing here honestly: Google revises the exact required signal names and behavior periodically, and this is a part of the system worth re-checking against current documentation at build time rather than trusting a snapshot from months ago — mine included.

The admin panel stays deliberately small

No user roles. No permissions matrix. One password, one form, one JSON file rewritten on save. It's tempting to over-build this into something closer to a real CMS, and I've resisted that every time — a single-admin settings screen is the right amount of tooling for what this actually needs to do. Adding multi-user access control would be a different, larger piece of software, not an extension of this one.

What this system doesn't do

It doesn't log consent events to a database for audit purposes — every decision lives only in the visitor's own cookie, which is simpler but means there's no server-side record to produce if ever asked to demonstrate historical consent patterns. It doesn't integrate with an ad-exchange-facing standard like IAB Europe's TCF, which matters only if a site participates in real-time bidding advertising networks; most small-to-mid business sites don't, and for those that do, this architecture isn't the right starting point.

Getting a working copy of this

Rather than publishing this as a downloadable plugin — which would mean maintaining compatibility promises and fielding support requests for configurations I can't test — I've written up the full technical specification as a blueprint document meant to be handed to an AI coding assistant along with your own site details: domain, colors, analytics IDs, languages. It generates the actual PHP and JavaScript tailored to your case, rather than a generic template you then have to reverse-engineer.

Scope and licensing

This architecture assumes a PHP-capable host and vanilla JavaScript on the frontend — no framework dependency, deliberately, since the sites it needed to run across weren't all built the same way. Whether it's worth adding server-side consent logging for a specific compliance requirement is a case-by-case decision this write-up doesn't make for you.

This description and the accompanying blueprint are provided for technical reference. Cookie categories, legal bases, retention periods, and policy content need to be defined with a qualified data protection advisor for your specific situation — this covers the consent mechanism, not a compliance guarantee.

How to use the blueprint, step by step

Four steps, no coding experience with this specific system required beyond basic familiarity with attaching a file to a chat.

1. Download the file. It's a plain .md text file, nothing to install or extract.

Download the Blueprint (.md)

2. Open a new conversation with an AI coding assistant. Claude works well for this, since the blueprint was written with that workflow in mind, but any capable assistant that can read an attached file and write PHP/JavaScript should handle it.

3. Attach the file and describe your site. Don't just upload it and ask "build this." Include your domain (or domains, if you need the multi-site version), your brand colors, whichever analytics or pixel IDs you actually use today, the languages your site needs, and links to your existing cookie and privacy policy pages. The blueprint lists exactly what to provide — that section exists precisely so nothing gets left out on the first pass.

4. Review before deploying. Check that the conditional loading actually gates every tracking script you use, that the Consent Mode v2 signals match Google's current documentation, and — this one isn't optional — have the cookie categories and policy text reviewed by whoever handles compliance for your business before it goes live on a real site.

One honest caveat: the output quality depends heavily on how specific step 3 is. A vague request produces a generic system that still needs the same reverse-engineering this blueprint was meant to avoid. A detailed one, with real IDs and real URLs, tends to produce something close to deploy-ready on the first attempt.

Need help with this solution or looking for custom development?

Visit my Stay In Touch page to connect and discuss your project. Discover a range of web development services and specialized WordPress solutions tailored to your needs. Let's work together to enhance your digital presence.