This page will go through some of the more advanced concepts and options available to display advertising.
o-ads can be configured to lazy-load ads (i.e. only trigger the ad call when the ad is in view, or close to being in view). This will allow viewability to improve, as we won’t be loading the ad until it is in view - but the tradeoff would be fewer ad impressions.
Lazy Loading uses Intersection Observer, so this needs to be polyfilled.
By default, lazy loading is disabled.
To enable lazy loading:
oAds.config({
lazyLoad: true
});
oAds.config({
lazyLoad: {
viewportMargin: '0% 0% 100% 0%',
threshold: [0.5]
}
});
<div class="o-ads" data-o-ads-lazy-load="false"></div>
There is one exception to lazy loading, which is Master/Companion. Based on the way that this pair of creatives are related in DFP, the companion is loaded soon after the master, which overrides lazy loading.
Options:
viewportMargin
- Sets a new margin within the viewport that determines at what point the advert is in view. We suggest setting this option when you want to request and display the advert just before it comes into view. This works as regular margin definitions.
Make sure you always specify the dimensions with either px
or %
, e.g. 100% 0%
, or 100px 0px
. Default is 0%
.
threshold
- An array of values that determine at what point a callback will be triggered.
In this case, the threshold is a percentage of the intersection area in relation to the area of the target’s bounding box (where the target is a DOM element relative to a containing element or to the top-level viewport). Intersection Observer.
Thresholds can be any value between 0.0 and 1.0, inclusive. Default is 0
, meaning that as soon as the first pixel comes into view, the advert will be loaded.
The library provide the option to check for invalid traffic before serving an ad. This relies on a third party script from Moat which you must include on your page, preferrably in the <head>
section on your page
<script async id="moat-ivt" src="https://sejs.moatads.com/financialtimesprebidheader859796398452/yi.js"></script>
This script will append the m_data
parameter to the ad call, with a value of 0 or 1. DFP will then use this parameter to decide whether to serve an ad or not.
To enable this feature make sure you have the script above on your page and enable the following config setting:
oAds.config({
validateAdsTraffic: true,
...
});
All ads get an attribute added called data-o-ads-loaded
, which contains the format of the ad that loaded. For example, data-o-ads-loaded="Billboard"
.
A product can use this to change the styles based on which ad has loaded (for example, to increase the height of a reserved slot if a larger ad loads).
The ad server can configure ads to come as a set - which is known as master/companion. This is used when, for example, an advertiser wants exclusivity on the page.
It is usually controlled by the ‘master’—the top slot—which has instructions around what other ads to bring down with it.
There is a quirk with Google’s implementation of master/companion ads which is that the ad calls must happen (more or less) immediately for the relationship to remain intact. This causes problems when used with Lazy Loading, as we cannot guarantee that a user would scroll to the other ads in time.
To work around this, we amend the lazy load behaviour so that if the first ad that loads is part of a master/companion set, we immediately trigger the next ad calls.
In addition - all ad slots will have an attribute added called data-o-ads-master-loaded
- which contains the format of the Master ad. An example use of this is on FT.com’s article page - where if we get a Responsive master/companion pair, we hide the sidebar ad and show a full width ad within the content.
A creative may not be served under one of the following circumstances:
A bug in the creative The ad server served an ad correctly, but some bug in the creative causes it not to display anything. A common example of this would be if the ad’s assets were insecure. This needs to be reported to AdOps as soon as possible - ideally with the creative Id or line item Id
Collapsed ad
This is when AdOps explicitly send instructions to an ad slot not to show anything. This is done via a particular creative that contains some code implemented throught o-ads-embed telling it to collapse itself. It should then append the class o-ads--empty
to the ad slot.
This is done in instances where an advertiser wants exclusivity on the page, but might not have assets with all the correct sizes.
There are three options available for how the ad slot should react to the absence of an ad.
before
: The ad slot will be collapsed before the ad request until an ad is found.
after
: The ad slot will be collapsed if no ad is found after the ad request.
never
: The ad slot never collapses, even if no ad is found.
By default, collapsing of empty ads is disabled (never
).
Via config for page level:
oAds.config({
collapseEmpty: "before",
...
});
Via config for a specific slot
oAds.config({
slots: {
outstream: {
collapseEmpty: "before"
}
},
...
});
<!-- view.html -->
<div class="o-ads" data-o-ads-name="outstream"></div>
Via component
<div class="o-ads" data-o-ads-collapse-empty="before"></div>
Out-of-page line items make it easier to serve web creatives that do not fit in a traditional banner space or browser window. They may include pop-ups and floating line items and are sometimes called interstitials.
To serve pop-up, pop-under, or floating creatives to your website, you’ll need to traffic the creatives using one of DFP’s built-in creative templates, and you’ll need to make sure your tags are set up properly to allow these creative types to serve. DFP traffic and serve out-of-page creatives
<div data-o-ads-out-of-page="true"></div>
To pass o-ads library version number along with ads call. (off by default)
``` javascript
oAds.config({
passOAdsVersion: true,
...
});
```
Will add `OADS_VERSION` key to ad calls with the current o-ads version in cust_params
oAds.initialising
Triggered when the library starts the initialisation process. At this point in time, if targetingApi
has been defined in the configuration, two separate calls are made to the targeting api in order to get ‘user’ and ‘page’ targeting parameters.
Also at this point, if validateAdsTraffic
is set to true
, o-ads
will check if the traffic validation script (currently moat.js
) is available and use it to check if the traffic source is a valid one.
oAds.adsAPIComplete
If targeting has been configured, this event is triggered when both requests to the targeting api (‘user’ and ‘page’) have been fullfilled (whether successfully or not).
oAds.IVTComplete
If validateAdsTraffic
is set to true
, this event is triggered as soon as the traffic has been validated or, if the traffic validation script can’t been found, when the associated timeout period expires.
oAds.initialised
Triggered when the library has been initialised and the config has been set. (Note: the GPT library may not have been loaded by this point).
oAds.serverScriptLoaded
Triggered when both the GPT library is loaded and oAds.initialised
has happened. This marks the completion of the page-level tasks required to enable requests to the ad server.
oAds.adServerLoadError
Triggered if the library fails to load the external JS GPT library, meaning no advertising will work. Can be used if you wish to have a fallback when you know the adverts will not display.
oAds.slotReady
Slot has been inited in the oAds library and is about to be requested from the ad server (deferred if lazy loading is on).
oAds.slotRenderStart
Triggered once the ad has been rendered on the page.
oAds.slotExpand
If and when a creative has been returned, this event announces it has now been initialised in oAds, requested from the ad server and displayed. Triggered after oAds.slotRenderStart
.
oAds.slotCanRender
Lazy loaded advert has been requested.
oAds.refresh
A refresh event has been triggered on an advert, prompting a new request to the ad server.
oAds.breakpoint
If the oAds is configured to use responsive adverts with set breakpoints, it will trigger the event on each of the breakpoints that was specified in the config. Note that the breakpoint triggering does not take the scrollbar into consideration. For more information read about DFP - Build responsive ads.
oAds.collapse
Event is emitted when the slot is collapsed. The event detail contains oAds slot instance.
The ads loading process can be divided in two phases: the page initialisation phase and the slot rendering phase.
During the page initialisation phase the following steps take place:
The following graph shows the flow of events during the page initialisation phase alongside the name of the events triggered by o-ads.
During the slot rendering phase the following steps take place:
The following graph shows the flow of events during the slot rendering phase alongside the name of the events triggered by o-ads.
o-ads
approach to monitoringAs of version 12 o-ads
includes some built-in functionality to help monitor the ads loading flow.
Firstly, o-ads
saves a performance mark every time it dispatches one of the many events that indicate a milestone in the ads loading process. The Performance API used for this is native browser functionality that provides high resolution time measurements.
On top of that o-ads
is now exposing a new method in the utils
module called setupMetrics
which enables setting up all ads-related metrics in one step.
setupMetrics
setupMetrics(eventDefArray, callback, disableSampling)
:
eventDefArray
: An array of configuration objects, each of which corresponds to one group of o-ads
events.callback
: A function that will be invoked for each of those groups, possibly multiple times for each. When invoked, the callback will receive an object with information about the timings associated to the events in the group.disableSampling
: (optional) A boolean indicating if the sampling specified in the eventDefArray
should be ignored. That is, when set to true
, no sampling will be applied. It’s default value is false
.Each of the configuration objects must include the following fields:
spoorAction
: a string indicating the name of the group.marks
: an array of strings indicating the name of the o-ads
events whose metrics we want to include in the group. Notice that the oAds.
preffix must be omitted.triggers
: an array of strings including all the o-ads
events that cause the callback to be invoked.It can optionally include:
multiple
: a boolean indicating if the callback can be called multiple times for thegroup. It’s false
by default.sampleSize
: a number between 0 and 1 indicating the probability the callback is actually called. If it’s omitted, the callback will be called every time one of the triggering events is dispatched.It’s easier to understand how to configure o-ads
with an example:
const metricsDefinitions = [
{
spoorAction: 'page-initialised',
triggers: ['serverScriptLoaded'],
marks: [
'initialising',
'IVTComplete',
'adsAPIComplete',
'initialised',
'serverScriptLoaded',
'consentBehavioral',
'consentProgrammatic',
]
},
{
spoorAction: 'slot-requested',
triggers: ['slotGoRender'],
marks: [
'slotReady',
'slotCanRender',
'slotGoRender',
],
multiple: true
},
{
sampleSize: 0.1,
spoorAction: 'slot-rendered',
triggers: ['slotRenderEnded'],
marks: [
'slotRenderStart',
'slotExpand',
'slotRenderEnded',
],
multiple: true
}
];
function sendMetrics (eventPayload) {
nUIFoundations.broadcast('oTracking.event', eventPayload);
}
function setupAdsMetrics () {
oAdsUtils.setupMetrics(metricsDefinitions, sendMetrics);
}
In this example there are four different metrics groups. The first one will invoke the callback whenever the trigger (oAds.serverScripLoaded
) is dispatched. The callback will receive an object including any available information about several potential time marks (initialising
, IVTComplete
, adsAPIComplete
, initialised
, serverScriptLoaded
, …). If there is no information about any of those marks, the callback will still be called without it. Since the multiple
parameter is missing, its default value of false
is assumed which means that, once called, the callback will not be called again for the same page view even if, somehow, oAds.serverScriptLoaded
was dispatched again.
slot-rendered
and slot-requested
config is similar to page-initialised
. However, the multiple: true
parameter allows the callback to be called as many times as their respective triggering events are dispatched during the same page view. Which, in this case, is the right thing to do since we expect a page to contain, potentially, multiple ad slots.
Finally, the sampleSize: 0.1
parameter on the slot-rendered
group randomizes the possibility that the callback is actually called when the oAds.slotRenderEnded
event is dispatched, giving it only a 10% chance. This can be used to reduce the number of total “monitoring” events that get fired across the user base.
clearPerfMarks
oAds.utils.clearPerfMarks
can clear entire groups of performance marks created during previous ad loading cycles by some setupAdsMetrics
configuration. This is specially useful in websites that behave like single-page applications and don’t automatically clear the browser’s performance entry buffer very often.
oAds.utils.clearPerfMarks(eventDefArray, groupsToClear)
eventDefArray
is an array of metrics groups expected to have the same structure as defined in setupMetrics.groupsToClear
is an array of metrics groups whose associated performance marks we want to remove.Example:
const metricsDefinitions = ... // as per the 'setupMetrics' example
// Clear all existing performance marks defined in the 'slot-rendered' and 'slot-rendered' groups
oAds.utils.clearPerfMarks(metricsDefinitions, ['slot-requested', 'slot-rendered']);
// With the previously defined `metricsDefinitions` array, this code will remove all
// `slotReady`, `slotCanRender`, `slotGoRender`, `slotRenderStart`, `slotExpand`
// and `slotRenderEnded` existing marks