Fallback tags and callbacks

No ad network fills every request. When PurpleAds has no ad for one of your Responsive Display Banners, you can decide what goes there instead: AdSense, another network, or your own code. There are three ways to set that up. The video player is different: it has no fallback, but it sends events your page can react to, and those are at the end.

Everything here applies to ad units you placed yourself. The floating banner, the interstitial and the automatic sticky ads are managed by us and do not take a fallback.

The quickest option. No code on your side beyond the ad code you already copied from your network.

  1. Open your website in the Publisher Dashboard and select the Responsive Display Banner ad unit.
  2. Open the Settings tab and turn on Banner Fallback.
  3. Paste the ad code from AdSense, or from any other network, into the box.
  4. Save.

From then on, whenever one of your banners goes unfilled, your code is placed inside that banner’s container. Two things make this safer than pasting the code into the page yourself.

The size is chosen for you. When we measure a container we work out which banner sizes fit it, the same measurement we use to pick our own ad. Your fallback gets that size. For AdSense we request a fixed-size ad at exactly those dimensions, which AdSense allows for any display ad unit, so a responsive unit cannot pick a taller ad and push your content down. For other networks, write {width} and {height} anywhere in the code and they are replaced with the numbers:

<div id="other-network-unit" style="width:{width}px;height:{height}px"></div>
<script src="https://cdn.other-network.example/tag.js" data-width="{width}" data-height="{height}" async></script>

The library loads once. If your code includes a script that is already on the page, such as the AdSense library, it is not loaded a second time. Paste the full code as the network gives it to you.

A few rules to know:

  • The fallback runs once per banner per page view. That banner is then yours: we do not refresh it or place an ad in it again until the next page load.
  • It runs after our request came back empty, or after 8 seconds with no answer at all, so a slow response from us does not leave your slot blank. The saved code reaches the visitor’s browser with your site settings, which are kept for a few minutes. During a full outage on our side, a visitor who has not loaded your settings recently gets no fallback. The code option below does not have this limit, because the function is already on your page.
  • It applies to Responsive Display Banners only, not to the floating banner, the interstitial or video ads.
  • It is not used when the banner is served through a Google Ad Manager creative. AdSense code does not belong inside another ad server’s creative, and Ad Manager has its own AdSense backfill for that case.
  • The PurpleAds banner code itself cannot be the fallback. It would ask us again for the slot we just passed on.
  • The code runs on your pages exactly as you paste it. Only paste code from a network you use.
  • An unfilled request shows in your PurpleAds reporting as a request without an impression. The fallback ad is counted and paid by the network that served it, not by us.

If you would rather decide on the page, define one function before or after the banner code. When it exists, we call it instead of using the code saved in the dashboard.

<script>
  window.purpleDisplay = window.purpleDisplay || {};
  window.purpleDisplay.onUnfilled = function(placement) {
    var size = placement.sizes[0];
    var ad = document.createElement('ins');
    ad.className = 'adsbygoogle';
    ad.style.display = 'inline-block';
    ad.style.width = size[0] + 'px';
    ad.style.height = size[1] + 'px';
    ad.setAttribute('data-ad-client', 'ca-pub-XXXXXXXXXXXXXXXX');
    ad.setAttribute('data-ad-slot', 'YYYYYYYYYY');
    placement.element.appendChild(ad);
    (window.adsbygoogle = window.adsbygoogle || []).push({});
  };
</script>

The function receives one object:

Field What it is
element The container you placed the PurpleAds snippet in. Append your ad to it.
sizes The banner sizes that fit the container, largest first, as [[width, height], ...]. Use the first one.
reason no-demand when we had no ad, timeout when our request did not answer within 8 seconds.
slotId Our id for that banner on this page view.
script The PurpleAds script tag itself.

The same rules apply as for the dashboard option: once per banner per page view, in-page banners only, and whatever you put in element stays there. If you use a tag manager, define the function in a tag that fires on page load. It is looked up at the moment a banner goes unfilled, so it only has to exist by the time our ad request returns.

Video ad events

The video player tells your page what it is doing, so you can pause your own player, log to analytics, or move the layout when an ad starts. There are two ways to listen.

Window events work with an async tag and do not depend on the player having loaded yet:

<script>
  window.addEventListener('purpleVideo:start', function(event) {
    console.log('video ad started', event.detail.ad);
  });
  window.addEventListener('purpleVideo:end', function(event) {
    console.log('video ad ended');
  });
</script>

Every event is sent twice: as purpleVideo:<name>, and as a plain purpleVideo event that carries all of them. event.detail includes type, the underlying player event, eventType, ad, data and timestamp. Playback events also include source, currentTime and duration. When the player runs inside an iframe, the events are sent on both the iframe window and the top window.

Once the player has loaded, window.purpleVideo.on(name, handler) and window.purpleVideo.off(name, handler) do the same thing. To register before an async tag has loaded, queue it the way Google Publisher Tag does:

<script>
  window.purpleVideo = window.purpleVideo || [];
  window.purpleVideo.push(function() {
    window.purpleVideo.on('play', function(payload) {
      console.log('video playing', payload.currentTime, payload.duration);
    });
  });
</script>

Event names: loaded, start, play, pause, resume, end, allAdsCompleted, adCanPlay, adBreakReady, adMetadata, progress, firstQuartile, midpoint, thirdQuartile, durationChange, skippableStateChanged, impression, click, interaction, skip, close, expandedChanged, linearChanged, videoClicked, videoIconClicked, volumeChanged, volumeMuted, error, contentPause, contentResume and contentEnd. adEvent fires for every raw ad event. A few have aliases: started for start, playing for play, paused for pause, resumed for resume, and ended or complete for end.

The close event depends on your video settings. If visitors may close the player and you chose to start again after 30 seconds, the payload carries refreshAfter: 30. If the player stays closed until the next page load, there is no refreshAfter.

Where to go next