Guides

Block scripts until consent: the four methods that work

To block a tracker until consent, mark its script tag as text/plain with a category, swap embed URLs for data-cq-src, or let the auto-blocker hold known trackers created by JavaScript.
Published 20 October 2026 · By the Cookiequiet team · Markdown

A banner that does not stop the scripts is the most common failure in cookie compliance, and the most expensive: the CNIL's largest recent fines (Shein, €150 million; American Express, €1.5 million; Condé Nast, €750,000) all cite cookies placed before the visitor made a choice or after they refused. Blocking means that analytics, advertising and embedded content do not load until the visitor consents to their category. There are four ways to achieve it, and most sites use two of them together: mark the script tags, swap embed URLs, let an auto-blocker catch what tag managers and lazy loaders create at runtime, and make each tag in a tag manager wait for consent.

Method 1: mark the script tag

Change the tag's type so the browser ignores it, and label it with its category:

html
<script type="text/plain" data-cq-category="analytics"
src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX"></script>
​
<script type="text/plain" data-cq-category="analytics">
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXX');
</script>

A browser never executes a script whose type is text/plain. When the visitor grants the category, Cookiequiet creates a new script element with the same attributes and the same content, sets its type to JavaScript, and inserts it right after the original, so both external and inline scripts run in their original order. Scripts whose category is refused stay inert.

Category names accepted in the attribute: necessary, functional, analytics, marketing, plus the aliases other banners use (statistics and performance for analytics, preferences for functional, advertisement, advertising and targeting for marketing, essential for necessary). The attributes data-cookieconsent, data-cookiecategory and data-category are read as well, which is what makes switching from Cookiebot a matter of replacing one script tag.

Method 2: hold embeds with data-cq-src

Iframes contact their host as soon as the browser sees a src. Move the URL to data-cq-src and the iframe stays empty until consent:

html
<iframe data-cq-src="https://www.youtube-nocookie.com/embed/VIDEO_ID"
data-cq-category="marketing" width="560" height="315"
title="Product demo" allowfullscreen></iframe>

When the category is granted, the src is set and the player loads. The category can come from the attribute, or from the provider database (a YouTube URL defaults to marketing, a Vimeo player to functional); when nothing is known, marketing is assumed. A placeholder with a "Load video" button that opens the preferences gives visitors a way to opt in on the spot; the YouTube guide has the markup.

Method 3: the auto-blocker

Tag managers, plugins and lazy loaders create script and iframe elements with JavaScript, after the page has loaded, where no markup of yours can catch them. The auto-blocker intercepts element creation: when a script or iframe is created and its src points to a known tracker whose category has not been granted, the element is held (its type set to text/plain, the URL kept aside) and released when consent arrives. The list of hosts comes from the site's configuration, built from a provider database of about 80 trackers; a short default list of the most common ones (Google Analytics, Google Ads, Meta, Hotjar, Clarity, TikTok, LinkedIn, Microsoft Advertising, Pinterest, YouTube embeds) is applied before the configuration even arrives, so there is no window at startup. Enable it in the dashboard, or with data-auto-block="1" on the snippet:

html
<script src="https://cookiequiet.com/cq.js" data-site="KEY"
data-consent-mode="1" data-auto-block="1" defer></script>

The honest limit: a tracker hard-coded in the HTML before this script, without the text/plain marking, runs before anything can stop it. Load the Cookiequiet script first in the head, and mark or move any tag that sits above it. The auto-blocker also cannot hold a tracker whose host is unknown to the database; mark those by hand.

Method 4: let the tag manager decide

If every tracker goes through Google Tag Manager, you can leave the container loaded and make each tag wait. Google's Consent Mode handles Google tags: with data-consent-mode="1" the defaults are set to denied before the container runs and updated on every choice, as explained in the Consent Mode guide. For other vendors, Cookiequiet pushes a cq_consent event with cq_functional, cq_analytics and cq_marketing flags; a trigger on that event with the right flag equal to true fires the tag only after consent. The event is pushed on page load when a stored choice exists, so returning visitors are covered.

What not to mark

Scripts the site needs in order to work (your framework bundle, a payment form's library on the checkout page, the search widget, the script that stores the consent choice itself) belong to the necessary category and should not be marked at all: they run for everyone, with or without consent, and the cookie policy explains why each is necessary. Marking them would make the site depend on the banner, and a visitor who refuses would get a broken page, which is a cookie wall in another form.

Any script of yours can wait for consent without being marked:

js
window.addEventListener('cq:consent', function (e) {
if (e.detail.categories.indexOf('analytics') >= 0) {
// start your analytics here
}
});

The window.Cookiequiet API exposes get() for the stored choice, on(callback) for changes, showPreferences() to open the centre, and acceptAll(), rejectAll(), save(categories) and withdraw() for custom buttons. An element with data-cq-show-preferences, or a link to #cq-preferences, opens the preferences when clicked.

Checking that nothing leaks

Open a private window with the developer tools, load the page and do not click. The Application tab should show only necessary cookies (the consent cookie, a session), and the Network tab no request to analytics or advertising hosts. Run document.querySelectorAll('script[type="text/plain"]') in the console to see the held tags. Click Reject all: nothing new should appear. Click Accept all: the tags run and the cookies arrive. Repeat on a page with embeds and on a page with a form, and after a tag manager change. The cookie audit checklist turns this into a routine.

Questions

No. It holds scripts and iframes created by JavaScript whose host is in the provider database, about 80 trackers. A tracker from an unknown host, or one hard-coded in the HTML above the consent script, is not caught; mark those tags yourself.
They work the same way. The marking is per tag, wherever it sits, and the consent script only needs to be loaded before them. Scripts after it, marked or on a known host, wait for consent.
The held and marked tags are activated at once, without a page reload, in their original order. Embeds get their src and load. The next page applies the stored choice before the tags run.
The marked tags stay inert, so analytics and advertising do not run, and the site itself keeps working. That is the safe failure for compliance. Scripts the site needs to function should not be marked at all.

Put a quiet banner on your website today

Free for one website with every core feature, no card and no trial clock. Upgrade a website to Starter for $3 a month to match your brand with AI and drop the branding, or to Pro for $9 to design it with the AI agent.