Why Consent Callbacks Matter for Script Control

A cookie banner is only half the job. The banner collects a decision, but your code needs to act on that decision - loading analytics after a visitor grants permission, or suppressing a tracking pixel when they refuse. Consent callback APIs bridge that gap.

Without a callback mechanism, developers often resort to polling the DOM or checking cookie values on a timer. Both approaches are fragile. A proper event-driven model lets your application respond the moment consent status changes, whether that happens on page load, after a banner interaction, or when a returning visitor's stored preferences are read from a cookie.

The practical difference is significant. Polling-based approaches introduce latency and race conditions. A callback fires synchronously with the consent action, giving your code a reliable signal to load or block third-party scripts based on cookie consent.

Core Consent Events Every CMP Should Expose

Most cookie consent platforms expose a small set of standard events. The naming varies between vendors, but the underlying pattern is consistent.

Event TypeWhen It FiresTypical Use Case
Initialise / ReadyCMP has loaded and read stored preferencesApply returning visitor's saved consent state
Consent UpdateVisitor interacts with the banner (accept, reject, or customise)Load or block scripts based on new choices
Category AllowA specific cookie category changes from denied to grantedFire a single tag (e.g. analytics) without checking all categories
Category RevokeA specific category changes from granted to deniedRemove cookies and stop data collection for that category
Banner ShowThe consent banner becomes visible in the DOMPause autoplaying content, adjust layout
Banner HideThe banner is dismissed or closedRestore page layout, trigger deferred actions

Your CMP documentation should list the exact event names. If it does not expose at least an initialise event and a consent-update event, that is a serious limitation worth flagging in any CMP evaluation.

Registering Event Listeners in JavaScript

The simplest integration pattern uses a global callback function that the CMP calls when consent changes. Here is a generic example:

window.addEventListener('consentUpdate', function(event) { var categories = event.detail; if (categories.analytics) { loadAnalytics(); } if (categories.marketing) { loadMarketingPixels(); } });

Some CMPs use a proprietary API instead of standard DOM events. A common pattern is a global function such as __cmp('addEventListener', callback) or a configuration object where you register handlers during initialisation.

Whichever approach your platform uses, three rules keep the integration reliable. Register your listener before the CMP script loads, so you never miss the initial event. Handle both first-visit and returning-visitor scenarios - the initialise event covers the latter. Clean up listeners on single-page application route changes to avoid duplicate script loads.

Handling the Initial Page Load

Returning visitors already have a stored consent decision. Your callback must handle this case, because the CMP will read the stored cookie and fire an initialise event rather than showing the banner.

A common mistake is wiring up script loading only to the banner interaction event. That approach works for new visitors but leaves returning visitors with a blank analytics setup until they interact with a preferences link. The initialise event solves this by providing the stored consent state on every page load.

Integrating with the IAB TCF API

If your site uses IAB Transparency and Consent Framework strings for programmatic advertising, the __tcfapi function is your primary interface. The TCF specification requires every compliant CMP to support three commands: ping, addEventListener, and removeEventListener.

The addEventListener command is the recommended way to access consent data since TCF v2.2, replacing the deprecated getTCData method. It works like this:

__tcfapi('addEventListener', 2, function(tcData, success) { if (success && tcData.eventStatus === 'useractioncomplete') { // Visitor has made a choice processTCString(tcData.tcString); } });

The eventStatus field tells you what triggered the callback. A value of tcloaded means stored consent was read. A value of cmpuishown means the banner appeared. And useractioncomplete means the visitor clicked a button. TCF v2.3, mandatory from February 2026, retains this same listener pattern while adding the Disclosed Vendors segment to the TC string.

Connecting Callbacks to Google Consent Mode

Google Consent Mode v2 uses a different signalling mechanism. Rather than exposing events you listen to, it expects your CMP to push consent updates via the gtag function. The flow typically looks like this:

On page load, set defaults to denied:

gtag('consent', 'default', { 'analytics_storage': 'denied', 'ad_storage': 'denied', 'ad_user_data': 'denied', 'ad_personalization': 'denied' });

Then, inside your CMP's consent callback, push an update:

gtag('consent', 'update', { 'analytics_storage': 'granted', 'ad_storage': 'granted', 'ad_user_data': 'granted', 'ad_personalization': 'granted' });

The ad_user_data and ad_personalization parameters became mandatory for EEA traffic as part of Google's Consent Mode v2 requirements. Your callback must map your CMP's category model to these four parameters. A typical mapping treats the "analytics" category as analytics_storage and the "marketing" category as the three advertising parameters.

Using addConsentListener for Real-Time Updates

Google Tag Manager also provides a gtagSet('developer_id', ...) and an addConsentListener function within custom templates. This listener fires whenever a specific consent type changes state. For developers building GTM-based consent integrations, this is the hook to use inside tag templates rather than relying on the CMP's own callback outside GTM.

Practical Patterns for Conditional Script Loading

The most common use of consent callbacks is conditional script loading. Here are three patterns ranked by complexity.

Pattern 1: Deferred Script Injection

Store blocked scripts with type="text/plain" and a data-consent-category attribute. When a callback fires for that category, swap the type to text/javascript" and the browser executes it. This works well for inline scripts and simple tag snippets.

Pattern 2: Dynamic Script Creation

Create and append <script> elements programmatically inside the callback. This gives you full control over load order and error handling. It is the right choice for tags that depend on each other, such as a Meta Pixel that needs the Facebook SDK loaded first.

Pattern 3: Tag Manager Consent Triggers

Push a dataLayer event from your callback and use it as a GTM trigger. Every tag that requires consent fires only when the trigger condition is met. This keeps consent logic centralised and avoids scattering script-injection code across your templates.

Handling Consent Revocation

Granting consent gets most of the attention, but revoking it is equally important. Under Article 7(3) of the GDPR, withdrawing consent must be as easy as giving it. Your callback API must handle the revocation event too.

When a visitor changes their mind and revokes marketing consent, your code should stop any running tracking, delete the relevant cookies, and prevent further data collection until consent is granted again. The technical challenge is that some third-party scripts do not provide a clean teardown method.

For scripts without a shutdown API, the safest approach is to reload the page after consent revocation. The fresh page load reads the updated preferences and simply never loads the revoked scripts. This is not elegant, but it is reliable and satisfies the GDPR requirement for effective withdrawal.

Debugging Consent Callbacks

Consent callbacks are invisible by nature - they fire silently in the background. That makes them difficult to test and verify. A few techniques help.

Add console.log statements inside every callback during development. Log the event name, the consent state object, and a timestamp. This gives you a clear timeline of what fired and when.

Use the browser's Application panel in Chrome DevTools to watch cookies appear and disappear as you interact with the banner. Cross-reference the cookie changes with your console output to confirm that your callbacks are producing the right results.

Test four scenarios at minimum: new visitor accepting all, new visitor rejecting all, returning visitor with stored consent, and a visitor who changes their preferences mid-session. Each scenario exercises a different code path through your callback logic.

Common Mistakes and How to Avoid Them

MistakeConsequenceFix
Registering listeners after CMP loadsMiss the initialise event for returning visitorsRegister listeners in <head> before the CMP script
Ignoring the revocation eventScripts continue running after consent is withdrawnHandle revocation with cookie deletion or page reload
Hardcoding category namesBreaks when CMP updates its category taxonomyMap CMP categories to your own constants
No error handling in callbacksA single script failure silences all subsequent tagsWrap each script load in try-catch
Loading scripts on every callbackDuplicate tags fire multiple timesTrack loaded state with a boolean flag per script

Frequently Asked Questions

What is a cookie consent callback API?

A cookie consent callback API is a set of JavaScript events and functions exposed by a consent management platform. It allows developers to run custom code in response to consent changes, such as loading analytics scripts when a visitor grants permission or deleting cookies when consent is revoked.

How do I listen for consent changes in JavaScript?

Register an event listener using your CMP's API before the CMP script loads. Most platforms use either standard DOM events (via window.addEventListener) or a proprietary global function like __cmp('addEventListener', callback). Check your CMP's documentation for the exact method.

Does the IAB TCF API support event listeners?

Yes. The TCF specification requires all compliant CMPs to support the addEventListener command via the __tcfapi function. This replaced the deprecated getTCData method in TCF v2.2 and remains the recommended approach in TCF v2.3.

How do consent callbacks work with Google Consent Mode?

Your CMP's consent callback should call gtag('consent', 'update', {...}) with the updated consent state. Google tags then adjust their behaviour automatically based on whether analytics_storage, ad_storage, ad_user_data, and ad_personalization are granted or denied.

What happens if I register my consent listener after the CMP loads?

You risk missing the initialise event that fires when the CMP reads a returning visitor's stored preferences. This means returning visitors may not have their scripts loaded until they interact with the banner again. Always register listeners before the CMP script tag.

Do I need to handle consent revocation in my callback?

Yes. Under GDPR Article 7(3), withdrawing consent must be as easy as giving it. Your callback should stop tracking scripts, delete non-essential cookies, and prevent further data collection when a visitor revokes their 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.

Start Free - Scan Your Website