Docs
Three steps. The first one matters most.
There is no plugin to install. You add one tag, tell it about anything it would not already recognise, and that is the whole job.
Step 1: Put the tag first in <head>
html<script src="https://solidcookie.com/c/YOURSITEKEY.js"></script>Being first matters. Auto-blocking works by watching the page as the browser builds it. A tracker the browser reached before our tag has already run, and a banner that cannot block what it claims to control is worse than no banner — because it looks like it works.
On this website the framework renders the tag at the very top of
<body>rather than in<head>. That works here because nothing precedes it; on your site, head is the place.WordPress, no plugin
Either add this to the child theme’s
functions.php:functions.phpadd_action('wp_head', function () { echo '<script src="https://solidcookie.com/c/YOURSITEKEY.js"></script>' . "\n"; }, 0); // priority 0 — before anything else in heador, better, drop this file in
wp-content/mu-plugins/solidcookie.php. An mu-plugin survives a theme change and cannot be switched off by accident.wp-content/mu-plugins/solidcookie.php<?php /* Plugin Name: SolidCookie */ add_action('wp_head', function () { echo '<script src="https://solidcookie.com/c/YOURSITEKEY.js"></script>' . "\n"; }, 0);Step 2: Tag anything that should wait
Common trackers are recognised and held automatically — Google Tag Manager and Analytics, Hotjar, Clarity, the Meta pixel, LinkedIn, TikTok, Pinterest, HubSpot, and the YouTube, Vimeo and Google Maps embeds. That covers most small sites.
The reliable mechanism, and the one to use for anything else, is to tag the script yourself:
html<script type="text/plain" data-consent="analytics" src="https://example.com/tracker.js"></script> <script type="text/plain" data-consent="marketing"> // inline code is held the same way fbq('init', '1234567890'); </script>A script with a non-executable type is never fetched or run by the browser, with or without our JavaScript. We restore it once the visitor allows that category. The categories are:
data-consent Category What goes in it necessary Strictly necessaryalways on Always on — the site cannot work without them. They cover page navigation, security, and remembering the cookie choice you make here. preferences Preferences Remember choices such as your language or region, so the site is presented the way you prefer. analytics Analytics Anonymous visit counts, so the site owner can see which pages are read and where people run into trouble. They do not identify you. marketing Marketing Ads and remarketing tags, which follow you across websites so advertising can be tailored to you and measured. Embeds and iframes
An iframe sets cookies the moment it loads, and on a brochure site the map on the contact page is often the only thing that needs consent. Known embed hosts are held automatically by parking the
src; to hold any other iframe, put its address indata-gdprs-srcinstead:html<iframe data-consent="marketing" data-gdprs-src="https://www.youtube.com/embed/VIDEOID" width="560" height="315"></iframe>reCAPTCHA is never blocked. It lives on the same host as Google Maps, and holding it would break the contact form on every site that uses it — an outage, not a leak.
Step 3: Give visitors a way back
Anyone must be able to change their answer later. Put a link or button with
data-gdprs-showin your footer and it reopens the banner showing their current choices. If you provide none, one is added for you — to your footer, or the end of the page if there is no footer — but it looks better when it is yours. The Cookie consent link at the bottom of this page is one.html<a href="#" data-gdprs-show>Cookie consent</a>To show the cookie table on your own page, add an empty
<div data-gdprs-declaration></div>and it is filled from the live declaration. Or link to the hosted pages, which exist from the moment a site is set up:hosted policy pageshttps://solidcookie.com/p/YOURSITEKEY/cookie-policy https://solidcookie.com/p/YOURSITEKEY/privacy-policy
The JavaScript API
// Open the banner, straight to the category panel
window.gdprs.show(true)
// What this visitor has agreed to, or null before they answer
window.gdprs.getConsent()
// → { id, ver, hash, action, choices: { analytics: false, … }, ts }
// Run something once consent is decided (fires on every change too)
window.gdprs.on('consent', (c) => {
if (c.choices.analytics) startAnalytics()
})
// Withdraw everything. Reloads the page — see below.
window.gdprs.withdraw()Everything hangs off window.gdprs, which exists once the banner has loaded its configuration. A gdprs:consent event is also dispatched on window with the same record as its detail.
Withdrawing reloads the page. Granting a category is easy — a held script is released and runs. Revoking one is not: a tracker that has already executed has already set its cookies, and no amount of DOM manipulation un-runs it. The only honest way to return the page to the visitor’s new choice is to load it again.
The banner renders inside a shadow root with all styles reset, so your CSS cannot reach it and it cannot reach your CSS. It uses no inline event handlers and no innerHTML; its own stylesheet lives inside the shadow root, so a Content-Security-Policy needs to allow that one style element.
If you build sites for other people
Agencies and site builders provision sites through the partner API with a key, and the tag is injected at serve time. Sites provisioned this way belong to the partner’s account. aisites is the first integration.
| POST | /api/v1/partner/sites | provision a site |
| GET | /api/v1/partner/sites/<key> | status and domains |
| PATCH | /api/v1/partner/sites/<key> | update name / domain list |
| DELETE | /api/v1/partner/sites/<key> | soft-delete (records kept) |
| PUT | /api/v1/partner/sites/<key>/policies/<kind> | generate and publish a policy |
| POST | /api/v1/partner/sites/<key>/scans | queue a scan |
| GET | /api/v1/partner/sites/<key>/scans | latest scan and findings |
Getting a site key
There is no dashboard yet. Sites are set up by hand, or through the partner API. Ask, and you will get a key and the tag above with it.
Or read what it costs first.