Why Script Blocking Matters for Cookie Compliance
Article 5(3) of the ePrivacy Directive is unambiguous: storing or accessing information on a visitor's device requires prior consent, unless the cookie is strictly necessary. That rule applies not just to cookies themselves but to every script that sets them. A Google Analytics tag, a Meta Pixel, or a HubSpot tracking snippet all drop non-essential cookies the moment they execute.
Regulators have made the consequences of ignoring this clear. In 2025, the CNIL issued 21 sanctions specifically for tracker violations, with fines forming part of a record EUR 486.8 million enforcement total for the year. Several of those cases involved scripts that loaded before any consent interaction occurred.
The fix is straightforward in principle: block non-essential scripts from running until the visitor actively consents. The implementation, however, requires choosing the right technique for your stack.
Three Approaches to Conditional Script Loading
There are three widely used methods, each with different trade-offs in complexity, control, and compatibility. The right choice depends on how your site manages tags and whether you use a tag manager.
| Method | Difficulty | Best For | Requires Tag Manager |
|---|---|---|---|
type="text/plain" attribute | Low | Static sites, hardcoded scripts | No |
| CMP callback API | Medium | Custom integrations, SPAs | No |
| GTM consent triggers | Medium-High | Sites already using Google Tag Manager | Yes |
Method 1: The type=text/plain Attribute
This is the simplest technique. Browsers only execute <script> elements when their type attribute is set to a JavaScript MIME type (or omitted entirely, which defaults to text/javascript). Changing the type to text/plain tells the browser to treat the content as inert text.
Here is a standard analytics script before modification:
<script src="https://example.com/analytics.js"></script>
And after:
<script type="text/plain" data-cookie-category="analytics" src="https://example.com/analytics.js"></script>
The data-cookie-category attribute (the exact name varies by CMP) tells the consent platform which category this script belongs to. When a visitor grants consent for that category, the CMP changes the type back to text/javascript and the browser executes it.
When to Use This Method
This approach works well for scripts embedded directly in your HTML. It does not require a tag manager and is easy to audit visually. The limitation is that it only works with asynchronous scripts. Inline scripts that other code depends on synchronously can break page functionality if deferred this way.
It also requires you to touch every script tag individually. On a site with dozens of hardcoded tracking snippets, that becomes tedious, which is why automated cookie scanning and script blocking tools exist.
Method 2: CMP Callback API
A more flexible approach is to use your consent management platform's JavaScript API to listen for consent events and load scripts programmatically. Rather than modifying script tags in the HTML, you write JavaScript that checks consent status and injects scripts into the DOM only after permission is granted.
How Callback-Based Loading Works
Most CMPs expose an event or callback mechanism. The pattern typically looks like this:
window.addEventListener('CookieConsentGranted', function(e) {
if (e.detail.categories.includes('analytics')) {
var script = document.createElement('script');
script.src = 'https://example.com/analytics.js';
document.head.appendChild(script);
}
});
This gives you fine-grained control. You can load different scripts based on which categories a visitor accepts, chain dependent scripts in the correct order, and handle edge cases like consent withdrawal.
If you are building custom integrations, the consent callback API pattern is worth understanding in depth. It is the foundation for connecting your CMP to any third-party service, including those that do not support tag managers natively.
Handling Consent Withdrawal
A script that has already executed cannot be "unloaded" from memory. When a visitor withdraws consent, you cannot retroactively remove the JavaScript that has run. What you can do is delete the cookies that script set and prevent the script from firing again on subsequent page loads. Your CMP should handle cookie deletion automatically, but any custom callback logic needs to account for the withdrawal scenario.
Method 3: Google Tag Manager Consent Triggers
Google Tag Manager offers built-in consent management through Consent Mode v2. This method is suitable if you already manage your tags through GTM, which many marketing teams do.
Setting Up Consent-Based Tag Groups
The process involves three steps. First, define default consent states in your GTM container. These should deny all non-essential categories (analytics_storage, ad_storage, ad_user_data, ad_personalization) until the visitor makes a choice. Second, connect your CMP to GTM so that consent signals update these states via gtag('consent', 'update', ...). Third, assign each tag to the appropriate consent category using GTM's built-in consent settings.
Google tags (Analytics, Ads, Floodlight) respect these consent signals natively. When analytics_storage is denied, GA4 fires in a limited "cookieless" mode and uses conversion modelling to estimate gaps. When granted, it operates normally.
Non-Google Tags in GTM
Tags from other vendors - Meta Pixel, LinkedIn Insight Tag, Hotjar - do not natively understand Google's consent signals. For these, you need to create custom triggers that check consent state before firing. A common pattern is to use a "Consent Initialisation" trigger that fires only when the relevant consent category has been granted. You can also use GTM's "Additional Consent Checks" feature to require specific consent types before a tag fires.
Be aware that GTM controls when tags fire, but it does not block scripts loaded outside of GTM. If you have hardcoded scripts alongside your GTM implementation, those still need the type="text/plain" treatment or CMP callback approach described above. A thorough approach means blocking the GTM container itself until consent is given, or using GTM's built-in consent initialisation triggers to manage everything from within the container.
Common Mistakes That Break Compliance
Script blocking is not difficult to implement, but several pitfalls catch developers and marketers regularly.
Loading Scripts Before the CMP Initialises
If your tracking scripts appear in the HTML before your CMP's script tag, they may execute before the consent platform has a chance to block them. Script order matters. Your CMP must load first, or you must use the type="text/plain" method to prevent premature execution regardless of load order.
Forgetting Inline Scripts and Iframes
Developers often focus on external <script src="..."> tags and overlook inline scripts that set cookies or <iframe> elements that load third-party content. A YouTube embed, for example, sets cookies through its iframe. These need blocking too, typically by replacing the src attribute with a data-src equivalent and restoring it after consent.
Not Verifying That Blocking Actually Works
Implementing script blocking without testing whether it works is a common failure. Open your browser's DevTools, clear all cookies, reload the page without interacting with the banner, and check the Application tab. If you see non-essential cookies like _ga, _fbp, or _gcl_au before consent, your blocking is broken. Automated scanning tools like the Kukie.io cookie scanner can help catch these issues across your entire site.
Choosing the Right Method for Your Site
For a static HTML site with a handful of tracking scripts, type="text/plain" is the fastest path. You can implement it in an afternoon and verify it works with a quick DevTools check.
For single-page applications or sites with complex third-party integrations, the CMP callback approach provides the most flexibility. It fits naturally into the event-driven architecture of modern JavaScript frameworks.
For marketing-heavy sites where a non-technical team manages tags through GTM, the consent trigger approach centralises control within a familiar interface. Pair it with Google Consent Mode v2 to handle Google's own tags and custom triggers for everything else.
Many production sites use a combination of all three. GTM handles the bulk of marketing tags, CMP callbacks manage custom integrations, and type="text/plain" catches any hardcoded scripts that slipped outside the tag manager.
Frequently Asked Questions
Does the type=text/plain method work with all CMPs?
Most consent management platforms support this technique, though the data attribute name varies. Some use data-cookie-category, others use data-cookieconsent or similar. Check your CMP's documentation for the exact attribute it expects.
Can I conditionally load scripts without a CMP?
Technically yes, by writing custom JavaScript that checks a consent cookie and loads scripts accordingly. However, a CMP also handles consent collection, storage, withdrawal, and audit logging. Building all of that from scratch is not practical for most teams.
What happens if a visitor withdraws consent after a script has already run?
The script cannot be unloaded from memory, but the cookies it set should be deleted. Your CMP should handle cookie removal on consent withdrawal. On the next page load, the script will not fire again because consent is no longer granted.
Do strictly necessary cookies need script blocking?
No. Scripts that only set strictly necessary cookies - such as session identifiers, shopping cart tokens, or security cookies - are exempt from consent under Article 5(3) of the ePrivacy Directive. These can load without restriction.
Does Google Tag Manager block scripts automatically with Consent Mode?
GTM controls when tags fire, not when external scripts execute. Google's own tags adjust their behaviour based on consent signals, but non-Google tags and any scripts outside GTM require separate blocking measures.
How do I test whether script blocking is working correctly?
Clear all cookies, reload the page, and check the Application tab and Network tab in Chrome DevTools before interacting with the consent banner. No non-essential cookies or tracking requests should appear until you grant consent.
Take Control of Your Cookie Compliance
If you are not sure which cookies your site sets, start with a free scan. Kukie.io detects, categorises, and helps you manage every cookie - so your visitors get a clear choice, and you stay on the right side of the law.