Troubleshooting Google tag pausing

Ad Manager and AdSense pausing

When integrating the Google advertising tags alongside the Clickio Consent on a webpage, there might be rare instances where they don't pause as expected due to various reasons. To address this, we provide specific codes that you can implement. Simply insert your selected code at the beginning of the page's head section, ensuring it's placed before any other Google Ad tags and prior to the Clickio Consent code.

Please mind, that the solution is intended only for directly installed plain Google ads tags, if you are using third party mediation solutions to display Google ads please refer to this article.

For more information, technical explanations, and custom integrations example please refer to this article.

AdSense
<script type="text/javascript">
  var adsbygoogle=window.adsbygoogle||[];
  adsbygoogle.pauseAdRequests=1;
  
  var consentCallbackQueue=function(e,o){var t=!1,n=!1;let a=[],g=!1,l=!1,s=function(){g=!0,a.map(function(e,o){void 0!==e&&(e(t,n),a[o]=void 0)})};return document.documentElement.addEventListener("clickioConsentEvent",function(o){var a;a=o.detail.state,l=!0,null===a?(t=!0,n=!0,s()):-1===a||(0===a?(t=!1,n=!1,s()):1===a&&(t=!!e.__lxG__consent__.getGoogleConsentMode(),n=!!e.__lxG__consent__.getPurposeOneAllowed(),s()))},!1),setTimeout(function(){l||document.documentElement.dispatchEvent(new CustomEvent("clickioConsentEvent",{detail:{state:null}}))},5e3),{push:function(e){g?e(t,n):a.push(e)}}}(window);
   
  consentCallbackQueue.push(function(e,o){e&&(adsbygoogle.pauseAdRequests=0)});
</script>
Ad Manager
<script type="text/javascript">
  var googletag=googletag||{};
  googletag.cmd=googletag.cmd||[];
  googletag.cmd.unshift(function(){window.googletag.pubads().disableInitialLoad()});

  var consentCallbackQueue=function(e,o){var t=!1,n=!1;let a=[],g=!1,l=!1,s=function(){g=!0,a.map(function(e,o){void 0!==e&&(e(t,n),a[o]=void 0)})};return document.documentElement.addEventListener("clickioConsentEvent",function(o){var a;a=o.detail.state,l=!0,null===a?(t=!0,n=!0,s()):-1===a||(0===a?(t=!1,n=!1,s()):1===a&&(t=!!e.__lxG__consent__.getGoogleConsentMode(),n=!!e.__lxG__consent__.getPurposeOneAllowed(),s()))},!1),setTimeout(function(){l||document.documentElement.dispatchEvent(new CustomEvent("clickioConsentEvent",{detail:{state:null}}))},5e3),{push:function(e){g?e(t,n):a.push(e)}}}(window);
  
  function displayAndRefreshSlotById(e){consentCallbackQueue.push(function(o,t){o&&googletag.cmd.push(function(){googletag.pubads().isInitialLoadDisabled()?googletag.pubads().getSlots().forEach(function(o){o.getSlotElementId()==e&&(googletag.display(e),googletag.pubads().refresh([o]))}):googletag.display(e)})})}
</script>

Mind that for the correct functioning of the code (i.e. ad slots refresh after consent state is determined) you should also replace the current Ad Manager display codes:

<script type="text/javascript">
googletag.cmd.push(function(){
	googletag.display('div-id-1');
});
</script>

with the provided wrapper code:

<script type="text/javascript">
displayAndRefreshSlotById('div-id-1');
</script>

This code will not call googletag.display before user consent, once it is received, it will push the command to the googletag queue and also call refresh for the slot, if isInitialLoadDisabled is true. If any tags are not replaced with the provided wrapper code (i.e. 3rd party codes), you should manually call refresh for the slot using the consentCallbackQueue.

AdSense & Ad Manager simultaneously
<script type="text/javascript">
  var googletag=googletag||{};
  googletag.cmd=googletag.cmd||[];
  googletag.cmd.unshift(function(){window.googletag.pubads().disableInitialLoad()});
  
  var adsbygoogle=window.adsbygoogle||[];
  adsbygoogle.pauseAdRequests=1;
  
  var consentCallbackQueue=function(e,o){var t=!1,n=!1;let a=[],g=!1,l=!1,s=function(){g=!0,a.map(function(e,o){void 0!==e&&(e(t,n),a[o]=void 0)})};return document.documentElement.addEventListener("clickioConsentEvent",function(o){var a;a=o.detail.state,l=!0,null===a?(t=!0,n=!0,s()):-1===a||(0===a?(t=!1,n=!1,s()):1===a&&(t=!!e.__lxG__consent__.getGoogleConsentMode(),n=!!e.__lxG__consent__.getPurposeOneAllowed(),s()))},!1),setTimeout(function(){l||document.documentElement.dispatchEvent(new CustomEvent("clickioConsentEvent",{detail:{state:null}}))},5e3),{push:function(e){g?e(t,n):a.push(e)}}}(window);
  
  function displayAndRefreshSlotById(e){consentCallbackQueue.push(function(o,t){o&&googletag.cmd.push(function(){googletag.pubads().isInitialLoadDisabled()?googletag.pubads().getSlots().forEach(function(o){o.getSlotElementId()==e&&(googletag.display(e),googletag.pubads().refresh([o]))}):googletag.display(e)})})}
  
  consentCallbackQueue.push(function(e,o){e&&(adsbygoogle.pauseAdRequests=0)});
</script>

You should also replace Ad Manager display codes with the wrapper code as explained in the Ad Manager section.

Ad Manager

AdSense and Ad Exchange

 

Google Tag Manager (GTM)

Step 1

Place this code in <head></head> section of the site, after Clickio Consent (CMP) line and before GTM script:

<script>
(window.__lxG__consent__ = window.__lxG__consent__ || {}).consentCallback = function (state) {
if (state !== -1) {(window.dataLayer = window.dataLayer || []).push({'event': 'consentReady'});}};
</script>

Step 2

Create a custom event trigger with Event name "consentReady": img01.png

Step 3

Add a new trigger in the Triggering section of the tag: img02.png

Read more about custom event triggers in Google Tag Manager.

 

Why ads might fail to pause?

The main reasons why the Clickio Consent (CMP) might not pause the ads, along with solutions, are listed below.

1. Ads are called before Clickio (GDPR) consent is triggered.

In certain cases, ad units might be called before Clickio Consent (CMP) has a chance to invoke the corresponding pausing mechanism.

2. Some other code on the page initiates refresh() of Ad Manager ad units.

Other scripts on the page can call refresh() of ad units. You can use Google Publisher Console to detect this behavior.

3. Advertising is shown by ad tags other than Ad Manager and AdSense

By default, Clickio Consent (CMP) only pauses Ad Manager and AdSense tags. If you have tags from other vendors on the site, they can communicate with Clickio Consent (CMP) using CMP Javascript API, which is a standard part of the IAB's Transparency and Consent Framework. Alternatively, the tags can be paused and unpaused using the consent tool's simplified API.

If you use Google Tag Manager to show ad tags, please refer to our GTM integration guide.

Some ad units fail to show (dynamic pages)

After the user's decision, the consent tool refreshes all ad units on the page. If new ad units are dynamically added on the page later (for example, when the new content is loaded in an infinite scroll), they need to be refreshed manually using refresh() method after calling display().

Also, third party ads solutions may rely on standardized TCF API, which is available after Clickio Consent (CMP) is loaded, but if those API commands are invoked before the tool is loaded (i.e. those 3rd party codes are placed earlier on the page or just load faster) - API is not available for them and their logic fails, to fix this, you must install special stub code on the page, which will proxy API requests till the consent tool is loaded.

Callback queue pausing solution

To help you solve more complicated cases, we've created a queue-based pausing/unpausing solution, which uses Clickio CMP Simplified API.

The following code will allow pausing any ads but is customized for Ad Manager and AdSense. Any parts can be omitted if there is no need for them.

// initialize AdManager globals
var googletag = googletag || {};
googletag.cmd = googletag.cmd || [];
// disable initial load for AdManager
googletag.cmd.unshift(function () {
    window.googletag.pubads().disableInitialLoad();
});

// initialize AdSense globals
var adsbygoogle             = window.adsbygoogle || [];
// pause AdSense requests
adsbygoogle.pauseAdRequests = 1;

// Consent tool logic ready queue
var consentCallbackQueue = (function (window, undefined) {
    // semaphores default values
    // Google requests allowed (Google Inc. and Purpose 1 consented)
    var clickioConsentGoogleAllowed     = false;
    // Purpose 1 consented (allows using cookies)
    var clickioConsentPurposeOneAllowed = false;

    let timeoutCallInSeconds = 5; // false to disable

    let queue                 = [];
    let startImmediately      = false;
    let consentCallbackCalled = false;

    let addFunction = function (callback) {
        if (startImmediately) {
            callback(clickioConsentGoogleAllowed, clickioConsentPurposeOneAllowed);
        } else {
            queue.push(callback);
        }
    };

    let runQueue = function () {
        startImmediately = true;
        queue.map(function (callback, i) {
            if (callback !== undefined) {
                callback(clickioConsentGoogleAllowed, clickioConsentPurposeOneAllowed);
                queue[i] = undefined;
            }
        });
    };

    // callback which is executed by CCT code upon consent state determination

    let consentCallback = function (consentState) {
        consentCallbackCalled = true;

        if (consentState === null) {
            // consent not applicable, non-eu user, executing queue right away

            clickioConsentGoogleAllowed     = true;
            clickioConsentPurposeOneAllowed = true;

            runQueue();
        } else if (consentState === -1) {
            // eu user, consent interface shown, cmp loaded, user has not decided yet, waiting for user consent
        } else if (consentState === 0) {
            // eu user, consent callback timeout, executing the queue

            // google does not serve ads for GDPR users without consent and reports errors - do not allow Google in this case
            clickioConsentGoogleAllowed     = false;
            clickioConsentPurposeOneAllowed = false;

            runQueue();
        } else if (consentState === 1) {
            // eu user, user consented, executing the queue
            // !IMPORTANT! consentState === 1 DOES NOT MEAN THAT USER ALLOWED EVERYTHING

            clickioConsentGoogleAllowed     = !!window.__lxG__consent__.getGoogleConsentMode();
            clickioConsentPurposeOneAllowed = !!window.__lxG__consent__.getPurposeOneAllowed();

            runQueue();
        }
    };

    document.documentElement.addEventListener(
        'clickioConsentEvent',
        function(event){ consentCallback(event.detail.state); },
        false
    );

    // in case of network problems in loading consent.js
    if (timeoutCallInSeconds) {
        setTimeout(function () {
            if (!consentCallbackCalled) {
                // calling function to trigger logic
                document.documentElement.dispatchEvent(new CustomEvent('clickioConsentEvent', {detail: {state: null}}));
            }
        }, timeoutCallInSeconds*1000);
    }

    return {
        push: addFunction
    };
})(window);

// function to display AdManager slot by it`s div ID
// it supports automatic slot refresh if disableInitialLoad was called before
// respects end user consent settings
function displayAndRefreshSlotById(slotId) {
    consentCallbackQueue.push(function (googleAllowed, purposeOneAllowed) {
        if (googleAllowed) {
            googletag.cmd.push(function () {
                if (googletag.pubads().isInitialLoadDisabled()) {
                    googletag.pubads().getSlots().forEach(function (slot) {
                        if (slot.getSlotElementId() == slotId) {
                            googletag.display(slotId);
                            googletag.pubads().refresh([slot]);
                        }
                    });
                } else {
                    googletag.display(slotId);
                }
            });
        }
    });
}

// unpause AdSense
// respects end user consent settings
consentCallbackQueue.push(function (googleAllowed, purposeOneAllowed) {
    if (googleAllowed) {
        adsbygoogle.pauseAdRequests = 0;
    }
});

The core of the logic is a special callbacks queue, which is consecutively executed upon consent determination (either user decides in the UI or consent state is read from the cookies). This queue mechanism is also fully functional for non-EU users, so no need for geo-based logic branching.

In the example above, there is also a utility function (displayAndRefreshSlotById) which incorporates adding callback to the consent queue and triggering display and refresh for the Ad  Manager slot found by its div ID. The implementation may vary for other advertising systems.