Skip to documentation content

Load order: why CookieBeam must run first

What CookieBeam can and cannot block when another script runs before it, how load-order problems are detected, and how to fix them for each install method.

CookieBeam blocks tags by intercepting them as they are added to the page and by wrapping the browser APIs they use to send data. That only works for code that runs after the CookieBeam script. Anything that runs earlier has already done its work by the time CookieBeam starts.

What can and cannot be blocked

When a tracking script runs before CookieBeam:

  • Its first requests are not blocked. A page view, pixel fire or configuration request sent while the script started up has already left the browser.
  • Cookies it already set stay set. If cookie cleanup is enabled for the banner, the cleanup engine afterwards removes the cookies your scan inventory lists for categories the visitor has not accepted, but each cookie existed until then.
  • Image pixels created with new Image() are not caught. The interceptor watches elements created with document.createElement and elements inserted into the page; an image object that is never inserted is neither.
  • fetch calls may escape. CookieBeam replaces window.fetch. A script that saved its own reference to the original fetch before CookieBeam ran keeps using the unwrapped function.

Some later activity is still intercepted, because CookieBeam patches shared prototypes and globals rather than individual scripts:

  • XMLHttpRequest requests opened later go through the patched prototype.
  • Later navigator.sendBeacon calls and new WebSocket connections go through the wrapped globals, as long as the script looks them up when it sends rather than keeping a reference taken before CookieBeam loaded.
  • New script, iframe and image elements the early script inserts later are checked like any other.

So an early script is partly contained, but its start-up traffic and cookies are not. The only reliable fix is to make CookieBeam run first.

How load-order problems are detected

CookieBeam reports load-order problems from two places, shown together on the banner Overview, the Deployment page and the Scanner page under Load order:

  • Live visitors. The published banner script checks, once per page view, which scripts appear before its own tag and which requests started before it loaded. Only the script's origin and path are sent (never query strings), inline scripts are matched against known vendor signatures inside the browser and only the vendor is reported, and no cookie or visitor identifier is read or sent. Banners published before this check existed report nothing until they are published again.
  • Scans. The cookie scanner performs the same check on every page it visits, before it interacts with the consent banner. It also reports pages where it could not find the CookieBeam script at all.

Visitors do not keep re-reporting what CookieBeam already knows. Next to the banner script, CookieBeam publishes a small known list (known.json) with a hash of every open finding. When a page has something to report, the script downloads that list once, drops the items it contains and sends only the rest. A small sample of known items is still sent, so an open finding keeps its last-seen time while the problem persists. The list is refreshed when you publish and once a day; nothing is stored on the visitor's device. If the list cannot be loaded, the script reports everything, as before. Banners published before the known list existed keep their old behavior until they are published again.

Each finding names the script or vendor, the page it was seen on, how severe it is, where it was seen and when. Scripts and requests are classified with the same rules as the scanner inventory; strictly necessary items are not reported. A finding that is not reported again for a week is treated as resolved. You can also mark a finding as fixed (it reopens if it is seen again) or dismiss it.

Fixing it

Script tag

Make the CookieBeam script the first element in <head>, above every other script, and load it without async or defer:

<head>
  <script src="https://cdn.cookiebeam.com/banner/PUBLIC_BANNER_ID/default/loader.js"></script>
  <!-- everything else after it -->
</head>

With async or defer, the browser keeps parsing and runs other scripts before CookieBeam.

WordPress

The CookieBeam plugin prints its tag very early on the wp_head hook, before scripts enqueued by themes and plugins. When a tracker still runs first, it is usually hard-coded in the theme's header.php above the wp_head() call, or printed by a plugin that hooks wp_head with an even earlier priority. Move the hard-coded tag below wp_head(), or print CookieBeam earlier with the cookiebeam_head_priority filter:

add_filter( 'cookiebeam_head_priority', function () {
    return -2000; // default is -1000
} );

Shopify

The CookieBeam app embed loads in the theme's head. Trackers pasted directly into theme.liquid above it run first. Move the hard-coded script below the app embed, or load it through Shopify's Customer Privacy API so it waits for the visitor's consent.

Google Tag Manager

When CookieBeam is installed through the GTM template, GTM injects it, so every tag that fires before it is outside its control. Fire the CookieBeam tag on the Consent Initialization – All Pages trigger and require consent on your other tags, as described in Install with Google Tag Manager. Google tags that run after a Consent Mode default is set respect that default, so they are reported with lower severity.