Troubleshooting ad pausing and unpausing

Introduction
Ad Manager
AdSense and Ad Exchange

Please refer to this article for additional methods of pausing AdSense or Ad Manager tags

Why ads might fail to pause?

The main reasons why the Consent Tool might not pause the ads, along with solutions, are listed below.

1. The ads are called before the Consent Tool is initiated.

In certain cases, ad units might be called before the Consent Tool 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, the Consent Tool only pauses Ad Manager and AdSense tags. If you have tags from other vendors on the site, they can communicate with the Consent Tool 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

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 the Consent Tool 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 the ultimate weapon - a queue-based pausing/unpausing solution.

Based on the Clickio simplified consent 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.

AdSense and Ad Manager pausing codes are based on the provided queue-based solution