Cookie blocking
What the script holds back until consent, what you must mark up, and what no script can block.
Rule of thumb: Pactbase recognises trackers by where they load from (Google, Meta, Clarity and so on). Anything your own page or server does by itself, such as an inline script, a Set-Cookie header or a fetch to your own API, it cannot recognise. You mark it up, or check consent in your code.
Make sure Consent Management, then Purposes, has a cookie purpose for each category you use. Visitors choose per purpose, and a category with no purpose can never be allowed.
What happens to each kind of cookie
| # | How the cookie or tracking happens | Blocked automatically? | What you do |
|---|---|---|---|
| 1 | Vendor script from a known tracker host | Yes, by host | Nothing |
| 2 | Vendor loader snippet (Meta Pixel, Clarity, LinkedIn, Bing) | Yes, the script it adds is held | Nothing |
| 3 | Tag added later by JavaScript or a tag manager | Yes, if its host is known. The tag manager container itself loads, the tags inside are held | Nothing |
| 4 | Third-party script Pactbase does not know | No | Give the host a category in Cookie Governance, then Trackers. Or mark it up, or use data-blocking="strict" |
| 5 | Inline script writing a cookie or storage | Yes for a category the visitor has not allowed: names from your scan and well-known tracker names. A name nobody categorised waits for "accept all" | Give each of your cookies a purpose after a scan, strictly necessary for those the site needs. Or mark the script up |
| 6 | Video or map iframe from a known host (YouTube, Vimeo) | Yes, with an "Allow and load" placeholder | Nothing. The first request may still go out because it is in the HTML. Mark it up with data-src if even that must not happen |
| 7 | Iframe from an unknown host | No | Mark it up with data-src and data-category |
| 8 | Tracking pixel created by JavaScript | Yes, if its host is known | Nothing |
| 9 | Tracking pixel written in the HTML | No: the browser requests it before any script runs | Mark it up, or use the vendor's JavaScript tag, or keep the pixel in noscript |
| 10 | Stylesheet or font from another host | Not held, because the page needs it | Self-host fonts if you want no outside request |
| 11 | Cookie set by your server (Set-Cookie) | Never: no browser script can stop a server header | Set it only after consent. Check consent on the server |
| 12 | fetch, XMLHttpRequest or sendBeacon that sets a cookie or sends tracking data | To a known tracker host, yes: the request does not go out until allowed. To your own or an unknown host, no | For your own endpoints, check pactbase.getConsent() first |
| 13 | Cookie set when the visitor clicks (wishlist, remember me) | Not by Pactbase | Fine if strictly necessary for what they clicked. Otherwise check consent in the click handler |
| 14 | IndexedDB or Cache storage written by a script | Same as the script that writes it | Mark that script up |
| 15 | Tracker on your own subdomain (CNAME to a vendor) | No: your own domain is never held | Mark it up |
| 16 | Strictly necessary cookies (session, CSRF, cart, the consent choice) | Never blocked, by design | Nothing |
The cookie guard
With data-blocking="auto" (the default) or "strict", the script also watches document.cookie, cookieStore.set and writes to localStorage and sessionStorage. A write of a category the visitor has not allowed is held, and written for real if they allow it later on the same page. Deleting a cookie always works.
A cookie name that neither your scan nor a known tracker name categorises is held until the visitor accepts everything. Your page can still read it back on that page view, but the browser does not store it and your server does not receive it. Cookies already on the device are never deleted for being unknown.
If your site needs its own cookies before a choice, give them the strictly necessary purpose in the cookie list, or add data-unknown-cookies="allow" to the script. data-blocking="manual" turns the guard off.
Marking up what Pactbase cannot recognise
Categories are strictly_necessary, functional, analytics and marketing. data-purpose targets one purpose, by id or exact name, instead of a whole category, and takes priority.
<!-- Inline code: does not run until analytics is allowed -->
<script type="text/plain" data-category="analytics">
document.cookie = 'site_visitor_id=...; path=/; max-age=31536000';
</script>
<!-- External script from a host Pactbase does not know -->
<script type="text/plain" data-category="marketing" data-src="https://tag.example-tracker.com/tag.js"></script>
<!-- Iframe: data-src instead of src -->
<iframe data-category="functional" data-src="https://www.google.com/maps/embed?pb=..." width="600" height="300"></iframe>
<!-- Image pixel: data-src instead of src -->
<img data-category="marketing" data-src="https://pixel.example.com/p.gif" width="1" height="1" alt="">
<!-- Stylesheet -->
<link rel="stylesheet" data-category="functional" data-href="https://widgets.example.com/chat.css">When the visitor allows the category, Pactbase restores type, src and href and the browser loads them. If they reject, nothing runs and no request is made. If they later withdraw, Pactbase deletes the cookies and storage keys it knows of. Code that already ran stays in memory until the page reloads: add data-reload-on-withdraw to the script to reload automatically.
To let one tag always load, add data-pactbase-ignore. Use it only for something strictly necessary.
Strict mode and unknown hosts
You can give any host a category from the scan's Trackers list. It takes priority over the built-in list, and a host also covers its subdomains. The list reaches the script over the network and is cached, so it applies from the second page view. For the first page of a first visit, data-blocking="strict" holds every script, iframe and image from an outside host that no list knows, then releases or holds each once your list arrives. If the list cannot be loaded, they are released.
Strict mode is opt-in. Held scripts run after the list arrives, so they can run out of page order. A page whose own scripts depend on a library from an unknown CDN can break.
Checking consent in your own code
window.pactbase = window.pactbase || [];
pactbase.push(['on', 'consent', function (state) {
if (state.categories.indexOf('analytics') !== -1) {
fetch('/api/track', { method: 'POST', body: JSON.stringify({ page: location.pathname }) });
}
}]);
// later, for example in a click handler
if (window.pactbase && pactbase.getConsent('functional')) saveWishlistCookie();The consent event fires on every page once the choice is known, and again whenever the visitor changes it.