Troubleshooting ad pausing and unpausing
Introduction
Clickio Consent Tool can be configured to pause ads while the user is making a decision. While in the vast majority of cases the setting works perfectly, sometimes the ads are not paused correctly with the default implementation. Alternatively, some ads might fail to show on the page after pausing. This guide will help you to troubleshoot and fix both problems.
How Consent Tool pauses ads
Ad Manager
The Consent Tool uses disableInitialLoad
to prevent Ad Manager ad units from rendering before the user's decision. After the user makes a choice, the Consent Tool sets necessary privacy preferences with setRequestNonPersonalizedAds()
and calls refresh()
for all ad slots that are present on the page. Please refer to the Ad Manager documentation for additional information.
AdSense and Ad Exchange
The Consent Tool uses Google recommended (adsbygoogle=window.adsbygoogle||[]).pauseAdRequests=1
command to pause loading ads, after consent state is determined and privacy settings set with requestNonPersonalizedAds
, (adsbygoogle=window.adsbygoogle||[]).pauseAdRequests=0
is called.
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.
-
Make sure
consent_*.js
is implemented on the page before the ads libraries (gpt.js
for Ad Manager). -
If
consent_*.js
is above the ad libraries, but the problem occurs (periodically or constantly), adddefer
attribute to the script tags (bothconsent_*.js
and advertising tags). This will tell the browser to respect tag order when executing while maintaining their asynchronous loading:<script defer type="text/javascript" src="//s.clickiocdn.com/t/consent_*.js"></script>
. -
Mind that
async
attribute allows random execution order of all the async scripts, that may cause unexpected behavior due to race conditions.
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
When the Consent Tool is implemented on the site, some dynamically inserted Ad Manager ad units might fail to show. This happens because, after disableInitialLoad
is activated on the page, it cannot be turned off.
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: 0}}));
}
}, 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