Origami Frontend Components & Services

Readme: o-ads

o-ads is not maintained by the Origami team. This means that the Origami team will not necessarily be able to help you with support requests. The people who maintain this component may be able to offer support, but it's not guaranteed.

This package contains the core functionality used by the FT in providing ads across all of its sites. This includes ft.com, howtospendit.com, ftadviser.com and other specialist titles.

This doc is specific to the o-ads library. For more information about the ads ecosystem at the FT, visit the Ads wiki

Note: This package is over 5 years old and will soon be deprecated in favour of more modern tools. Please speak to the advertising team (Slack #advertising-dev) if you are thinking of using this.

Table of Contents

1. Install

2. Setup & Configuration

3. Define Ad Slots

4. Targeting

5. Lazy Loading

6. Invalid Traffic

7. Styling

8. Collapsing

9. Events

10. Metrics & Monitoring

11. Misc

12. Developing

13. Migration


Check out how to include Origami components in your project to get started with o-ads.

Setup & Configuration

Intialise the library

Step two. You'll need to initialise the o-ads library with some confirguration options in order for it to work. There are 2 ways of doing this:


If you've included o-ads directly on your site using the script provided above, you'll need to initialise it declaratively like so:

<script data-o-ads-config type="application/json">
  "gpt": {
    "network": 5887,
    "site": "test.5887.origami"

Note: See below for all config options

#### Programatically

If you've include o-ads in you code through npm, you will need to initialise it like so:

// your/app/ads.js
import oAds from '@financial-times/o-ads';
  gpt: {
    network: 5887,
    site: "test.5887.origami"
  ...other config options

Note: See below for all config options

Configuration Options {#config-options}

These are all the valid configuration options that can be used to set up o-ads:

Define Ad Slots

Step three. Create some ad slots. Once you've included and configured o-ads onto your website, you'll want to create some placeholders for your ads. These are the HTML elements where the ad will render. These can be defined declarately within a HTML page.

The Simplest Ad

This is the minimum required for an ad slot to be defined. We set some options via html attributes on the slot element. We are naming the ad slot exampleAdSlot and tell it to only return ads of the format MediumRectangle. This will be processed by o-ads and an ad will be rendered inside the <div> if the ad request is successful.


See Ad Formats and Breakpoints

Ad slot options {#ad-slot-options}

These are all the options that an ad slot can have, declared as attributes on the html element (see example above)

Ad Formats

Formats are predetermiend ad sizes that you can request for your ad. You can specify one format as in the above example, or you can specify multiple formats for different breakpoints. The following example loads a MediumRectangle ad at the small breakpoint, a Leaderboard ad at the medium breakpoint a SuperLeader ad at the large breakpoint and no ad at the extra large breakpoint.


Default breakpoints {#breakpoints}

The default breakpoints provided in o-ads are as follows:

Note: You can change the breakpoint definitions with the responsive config property:

  responsive : {
    extra : [1400, 0],
    someOther: [1200, 0],
    large : [1000, 0],
    medium : [600, 0],
    small : [0, 0]
  // where each array is in the format [width, height]

Default Formats {#formats}

Here are all the available ad formats and their corresponding ad sizes:

Format Name Size
MediumRectangle (MPU) 300x250
Rectangle 180x50
Leaderboard 728x90
SuperLeaderboard 970x90
Billboard 970x250
Responsive 2x2
WideSkyscraper 160x600
HalfPage 300x600
Portrait 300x1050
AdhesionBanner 320x50
MicroBar 88x31
Button2 120x60

Note: You can ad extra formats with the formats config option when initialising o-ads:

  formats: {
    testFormat: {sizes: [[970, 90], [970, 66], [180, 50]]}


Ads can contain extra information about a user, page, or any other useful info that could be used in Google Ad Manager. There are three ways of adding targeting information to an ad request.

Page level targeting

You can specify an object of key => value pairs when initialising o-ads. Each key => value pair will be appended to every ad request on the page

  targeting: {
    key: "value",
    key2: "value2",

Ad slot level targeting

You can also specify targeting parameters for any particular ad slot, by using the data-o-ads-targeting attribute when defining the ad slot:


Lazy Loading

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). It is disabled by default

Lazy Loading uses Intersection Observer under the hood.

  lazyLoad: true

// or

  lazyLoad: {
    viewportMargin: '0% 0% 100% 0%',
    threshold: [0.5]

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.


o-ads provides some classes to add some basic branded styling to the ad slot.


A creative may not be served under one of the following circumstances:

  1. 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

  2. Collapsed ad - This is when AdOps explicitly send instructions to an ad slot not to show anything, maybe because an advertiser wants exclusivity on the page, but might not have assets with all the correct sizes. 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.

  3. No ad This is when the ad server fails to return any ad. This could be caused by an ad call that is missing the correct targeting parameters and ad unit. However, it should be rare, as AdOps usually fall back to either programmatic advertising or House Ads

Collapsing of empty ad slots

There are three options available for how the ad slot should react to the absence of an ad.

  1. before: The ad slot will be collapsed before the ad request until an ad is found.

  2. after: The ad slot will be collapsed if no ad is found after the ad request.

  3. 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:

    collapseEmpty: "before",

Via config for a specific slot

    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>



Triggered when the library starts the initialisation process.


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).


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.


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.


Slot has been inited in the oAds library and is about to be requested from the ad server (deferred if lazy loading is on).


Triggered once the ad has been rendered on the page.


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.


Lazy loaded advert has been requested.


A refresh event has been triggered on an advert, prompting a new request to the ad server.


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.


Event is emitted when the slot is collapsed. The event detail contains oAds slot instance.

Metrics & Monitoring

As 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. If used from n-ads, extra performance marks might be added. See the n-ads docs


o-ads is now exposing a new method, oAds.utils.setupMetrics() which enables setting up all ads-related metrics in one step.

setupMetrics(eventDefArray, callback, disableSampling):

setupMetrics() Example

It’s easier to understand how to configure o-ads with an example:

const metricsDefinitions = [

        spoorAction: 'page-initialised',
        triggers: ['serverScriptLoaded'],
        marks: [
        spoorAction: 'slot-requested',
        triggers: ['slotGoRender'],
        marks: [
        multiple: true
    sampleSize: 0.1,
        spoorAction: 'slot-rendered',
        triggers: ['slotRenderEnded'],
        marks: [
        multiple: true

 function callback(eventPayload) {
    nUIFoundations.broadcast('oTracking.event', eventPayload);

oAds.utils.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.


Clear entire groups of performance marks created during previous ad loading cycles by some setupMetrics() 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)

clearPerMarks() 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


Changing behaviour based on which ad loads {#ads-loaded}

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).


Install & Demos


See the test documentation


You will need a GITHUB_TOKEN environment variable with access to the repository in your .env file
Get a github token with "repo" access and make it accessible as an environment variable.

Run npm run release (patch|minor|major|x.y.z) in master then follow the interactive steps.

This will bump version numbers in the source and commit them, push to github and create a new release.

The command uses release-it under the hood as well as genversion to automatically bump version numbers in the source.


See the migration guide

active Origami v1 (Bower)
Switch component view

GitHub: o-ads

Install o-ads

If using the Build Service, add o-ads@^19.0.1 to your script and link tags.

If using the npm package manager for a Manual Build, run npm install --save-peer "@financial-times/o-ads@^19.0.1".

Help & Support

o-ads is not supported directly by the Origami team. We make no guarantees, but will help if we can. First try contacting its maintainers at:

Slack: #advertising-dev
Email: origami.advertising.technology@ft.com