DFP Ad Tagging Implementation Analysis for Desktop and Mobile Platforms of a Client Site

Got a chance to analyze a client site and check how DFP ad tags was implemented on desktop and mobile platforms.

In a nutshell, the site renders a leaderboard banner that sticks to the bottom of the page of a Single Page App (SPA) — (a web application where you can draw anything you want, really nice though) — that is refreshing every 30 seconds.

What to expect:

  • Check how the site was tagged in desktop and mobile
  • Provide analysis and recommendations

After minutes of checking, here’s what I’ve found.

Based on the Header tag below Ad slot is not responsive the ad slot only supports 728×90 ad size.

<script async="async" src="https://www.googletagservices.com/tag/js/gpt.js"></script>
<script>
     var googleBottomAd, adRefreshInterval;
     var googletag = googletag || {};
     googletag.cmd = googletag.cmd || [];
     googletag.cmd.push(function() {
     googleBottomAd = googletag.defineSlot('/ID/ad-unit', [728, 90], 'div-gpt-ad-1511792237949-0').addService(googletag.pubads());
     googletag.pubads().enableSingleRequest();
     googletag.pubads().addEventListener('slotRenderEnded', function(event) {
     var adWrapper = document.getElementById('google-ad-wrapper');
     if (event.isEmpty) {
          adWrapper.style.display = 'none';
     } else {
          adWrapper.style.display = 'initial';
     }
     });
          googletag.enableServices();
     });
</script>

The snippet below was taken from the client script that checks if a user is authenticated and set account details and application features.

function H() {
     it.fetch({ url: "/api/v2/check-login/", query: { apiKey: rt.apiKey }, json: !0, cors: !0, withCredentials: !0 },function(t, e, n) {
if (n.isAuth) {
var r = !!n.hasTrial,i = n.trialDays,o = st.boardInfo(),s = st.boardCanDo();
st.currentUser().email = n.email, st.currentUser().nick = n.name, st.currentUser().isPremium = n.features.advancedTools, st.currentUser().hasTrial = r, st.currentUser().avatarThumbUrl = n.avatarThumbUrl, st.currentUser().segment = n.segment, st.currentUser().accountType = n.accountType, st.currentUser().key = n.key, st.currentUser().enableClassroom = n.enableClassroom, st.currentUser().shownTips = n.shownTips || [], st.currentUser(st.currentUser()), o.isAdmin = !0, st.boardInfo(o), a.each(s, function(t, e) { n.features && n.features[e] && (s[e] = n.features[e]) }), st.boardCanDo(s), "awwapp-api-key" === st.boardInfo().ownerKey && G(), n.colors && et.emit("set-user-custom-colors", n.colors), et.emit("update-ui"), et.emit("userLoggedIn", { email: n.email, trialDaysLeft: i, hasTrial: r }), Q && (et.emit("flash-message", "Nice to have you back :)", "success", 3), Q = !1)
} else et.emit("userLoggedOut");(!n.isAuth || !st.currentUser().isPremium) && J && window.innerWidth > 828 && q("showAdsOnAccountLoad") })
}

If the user is not authenticated or not a premium user and is viewing the app in a browser that is > 828px wide then it will run the q() function below.

function q(t) { void 0 === window.localStorage.adtag && (window.localStorage.adtag = Math.floor(10 * Math.random()) + 1), "1" == window.localStorage.adtag && et.emit(t) }

The q() function above checks if a localStorage variable “adTag” exists. If it’s not set it will be created and randomly set the value ranging from (1-10).

If the adTag value is equal to ‘1’, an event called “showAdsOnAccountLoad” will be emitted then executes the callback function called “showAds”.

[code]<script>aww._dispatcher.on(‘showAdsOnAccountLoad’, showAds);</script>[/code]

The showAds() function then creates the ad wrapper and container where the ad will be displayed. The ad display tag is set to refresh in a 30 seconds interval.

function showAds() {
     var awwWrapper = document.getElementsByClassName('aww')[0];
     // awwWrapper.style.height = 'auto';
     // awwWrapper.style.bottom = '110px';
     
     var adWrapper = document.createElement('div');
     adWrapper.id = 'google-ad-wrapper';
     adWrapper.style.position = 'absolute';
     adWrapper.style.bottom = '0';
     adWrapper.style.zIndex = '1';
     adWrapper.style.minWidth = '60%';
     adWrapper.style.marginLeft = '20%';
     adWrapper.style.height = '112px';
     adWrapper.style.background = '#56C376';
     
     var CTAtext = document.createElement('p');
     CTAtext.innerText = 'No ads and more features in premium version. ';
     CTAtext.style.textAlign = 'center';
     CTAtext.style.margin = '3px';
     CTAtext.style.fontWeight = '300';
     CTAtext.style.fontSize = 'small';
     
     var CTAlink = document.createElement('a');
     CTAlink.href = '/info/plans';
     CTAlink.target = '_blank';
     CTAlink.onclick = function(e) {
     if (isLocalStorageAvailable() && !window.localStorage.isAuthenticated) {
     e.preventDefault();
     aww._dispatcher.emit('widget-register');
     }
     gaSend('Ads CTA', 'No ads and more features in premium version. Sign up here. Logged in: ' +
     (isLocalStorageAvailable() ? window.localStorage.isAuthenticated : ''));
     };
     CTAlink.innerText = 'Sign up here.';
     CTAlink.style.color = 'white';
     CTAlink.style.textDecoration = 'underline';
     CTAlink.style.fontWeight = '600';
     
     var ad = document.createElement('div');
     ad.id = 'div-gpt-ad-1511792237949-0';
     ad.style.width = '728px';
     ad.style.height = '90px';
     ad.style.margin = '0 auto';
     
     CTAtext.appendChild(CTAlink);
     adWrapper.appendChild(CTAtext);
     adWrapper.appendChild(ad);
     awwWrapper.parentElement.appendChild(adWrapper);
     
     googletag.cmd.push(function() {
          googletag.display('div-gpt-ad-1511792237949-0');
          adRefreshInterval = setInterval(function () {
          googletag.pubads().refresh([googleBottomAd]);
          }, 30000);
     });
}

If the adTag value is not equal to ‘1’, the following warning will be thrown in DFP console because the DFP header tag was initialized without a matching display call or a non-existent body tag which can sometimes cause un-necessary ad requests to the DFP ad server.

DFP warning google tag defined a slot without a matching tag

To prevent that to happen, enclose the DFP Header tag declaration within a logic where it checks first if the adTag key exists in localStorage and the value is equal to ‘1’.

While on mobile, no ad will be shown as the “showAdsOnAccountLoad” event only gets fired when a brower’s viewport is greater than 828 pixels wide.

As I suggest–to serve ads on mobile–client needs to do the following changes:

  1. Create a responsive ad size mapping for the ad slot to support (320×50 or 320×100) ad sizes and update the tags in the header.
  2. Remove the logic (window.innerWidth > 828) that checks the browser’s viewport in the client’s main application script.
  3. Update the ad unit to support (320×50 or 320×100) ad sizes in Google DFP ad server.
  4. Create a line-item in Google DFP that is targeted to mobile and traffic tags from demand partners.

Add comment

E-mail is already registered on the site. Please use the Login form or enter another.

You entered an incorrect username or password

Sorry, you must be logged in to post a comment.

Join our list

Subscribe to our mailing list and get interesting stuff and updates to your email inbox.

Thank you for subscribing.

Something went wrong.

Done