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.
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:
- 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.
- Remove the logic (window.innerWidth > 828) that checks the browser’s viewport in the client’s main application script.
- Update the ad unit to support (320×50 or 320×100) ad sizes in Google DFP ad server.
- Create a line-item in Google DFP that is targeted to mobile and traffic tags from demand partners.