Skip to content

Holding back third-party scripts ​

A tag that sets cookies has to wait for consent. There are two ways to make it wait, and they are not equally strong — pick by whether you can edit the tag.

If you can edit the tag: mark it ​

Change the type and name the category:

html
<script type="text/plain" data-category="analytics"
        src="https://example-analytics.com/tracker.js"></script>

The browser will not touch a script whose type it does not recognise, so nothing is fetched and nothing runs until the visitor accepts. This is the strongest option and the one to use whenever the tag is yours to change.

The other markers you can use ​

Four more attributes, honoured on the GDPR banner and the US notice alike.

AttributeWhat it does
data-src="…"Park the URL here instead of in src. A script with no src and no body runs nothing, so this holds the tag on its own — useful when you cannot change the type.
data-type="module"The type to restore on release. Needed for a module: released as a classic script, its first import is a syntax error.
data-service="Google Analytics"Names the service inside the category. On the GDPR template a visitor can refuse one service inside a category they accepted; on the US template there is one statutory control and no per-service choice, so the category decides.
data-category="!analytics"The opposite: run this only while the category is refused. For a cookieless fallback, or a notice where an embed would have been. The name has to be one of your own categories, so a typo cannot turn into "run this always".

Marked scripts run in the order you wrote them. One with a URL is waited for before the next is started, so a library and the snippet that calls it stay in step — write the library first and its initialiser second, exactly as you would without consent in the way.

If you cannot: give us the URL ​

For tags you do not control — injected by a tag manager, added by a plugin, buried in a theme — add the pattern next to the cookie the tag sets, under Manage cookies, in the Script URL pattern field. A fragment of the URL is enough:

The scriptThe pattern
https://cdn.luigisbox.tech/search.jsluigisbox.tech
https://connect.facebook.net/en_US/fbevents.jsconnect.facebook.net

Any script whose URL contains it is held until the cookie's category is accepted, then loaded. One pattern covers every cookie from that vendor — you do not need to repeat it per cookie.

What this can and cannot block ​

It depends on how the script gets onto the page

How the tag arrivesRequest sent?Script runs?
Built by JavaScript — a tag manager, a pluginNoNo
Written into your HTMLYesNo

The second row is a limit of the browser, not a setting. A script written into the page starts downloading the moment the parser reaches it, which is before any code of ours can look at it. What we prevent is execution — and execution is what sets cookies, reads storage and identifies the visitor. The request itself still reaches the vendor with an IP address and a Referer.

So for a tag in your own HTML, the type="text/plain" marking above is the complete answer, and the URL pattern is the fallback. For a tag manager's output, the URL pattern is the only handle there is — and there it stops the request too.

No CMP does better with JavaScript alone; anything claiming otherwise is blocking the same two ways.

A held script is loaded and run when its category is accepted. It is rebuilt from what was captured, in its original place, with its attributes intact — as close to a normal load as the browser allows, but not identical:

  • a script that uses document.write will not write into the page the same way
  • a script that expects to run before something that has already run will not get that order back

Both are inherent to holding a script back at all. If a vendor's tag misbehaves after consent, mark it with type="text/plain" instead — held from the start, it never has to be restarted.

Choosing a pattern ​

Keep it specific enough to name one vendor. luigisbox.tech is a good pattern; box would match anything with those three letters in its URL, including your own application bundle, and the page would break for everyone who has not consented.

Patterns are matched as plain text, anywhere in the URL, case-insensitively.

Nothing is blocked unless you ask

CookieWave never infers a pattern from a scan, even though the scan records which script set each cookie. A rule that matches too much takes a working site down, and the only person who knows what a pattern is for is whoever typed it.

Necessary cookies are never blocked ​

A pattern on a cookie in the necessary category is ignored. Nothing can consent to that category, so the script would wait for ever — a broken site rather than a compliant one. If a tag genuinely must not run before consent, it is not necessary; move it to another category.

Checking it works ​

Open your site in a private window, before accepting anything, and look at the network panel:

  • filter by the vendor's domain — a tag manager's script should not appear at all
  • a script in your HTML will appear; check the console instead: its cookies must be absent

Then accept, and both should appear.

CookieWave consent management