Skip to main content

Ad tracking

Snowplow tracking code can be included in ad tags in order to track impressions and ad clicks. This is used by e.g. ad networks to identify which sites and web pages users visit across a network, so that they can be segmented, for example.

Each ad tracking method has a costModel field and a cost field. If you provide the cost field, you must also provide one of 'cpa''cpc', and 'cpm' for the costModel field.

It may be the case that multiple ads from the same source end up on a single page. If this happens, it is important that the different Snowplow code snippets associated with those ads not interfere with one another. The best way to prevent this is to randomly name each tracker instance you create so that the probability of a name collision is negligible. See Managing multiple trackers for more on having more than one tracker instance on a single page.

Snowplow ad events must be manually tracked.

Install plugin

Tracker DistributionIncluded
sp.js
sp.lite.js

Download:

Download from GitHub Releases (Recommended)Github Releases (plugins.umd.zip)
Available on jsDelivrjsDelivr (latest)
Available on unpkgunpkg (latest)

Note: The links to the CDNs above point to the current latest version. You should pin to a specific version when integrating this plugin on your website if you are using a third party CDN in production.

window.snowplow('addPlugin', 
"https://cdn.jsdelivr.net/npm/@snowplow/browser-plugin-ad-tracking@latest/dist/index.umd.min.js",
["snowplowAdTracking", "AdTrackingPlugin"]
);

Events

The ad tracking plugin includes three event types: ad impression, ad click, and ad conversion.

Impression

Ad impression tracking is accomplished using the trackAdImpression method. Here are the arguments it accepts:

NameRequired?DescriptionType
impressionIdNoIdentifier for the particular impression instancestring
costModelNoThe cost model for the campaign: 'cpc', 'cpm', or 'cpa'string
costNoAd costnumber
targetUrlNoThe destination URLstring
bannerIdNoAdserver identifier for the ad banner (creative) being displayedstring
zoneIdNoAdserver identifier for the zone where the ad banner is locatedstring
advertiserIDNoAdserver identifier for the advertiser which the campaign belongs tostring
campaignIdNoAdserver identifier for the ad campaign which the banner belongs tostring
note

All properties are optional but you must specify at least 1 for this to be a valid call to trackAdImpression.

An example:

snowplow('trackAdImpression', {
impressionId: '67965967893',
costModel: 'cpm', // 'cpa', 'cpc', or 'cpm'
cost: 5.5,
targetUrl: 'http://www.example.com',
bannerId: '23',
zoneId: '7',
advertiserId: '201',
campaignId: '12'
});

Ad impression events are implemented as Snowplow self describing events. Here is the JSON schema for an ad impression event.

Click

Ad click tracking is accomplished using the trackAdClick method. Here are the arguments it accepts:

NameRequired?DescriptionType
targetUrlYesThe destination URLstring
clickIdNoIdentifier for the particular click instancestring
costModelNoThe cost model for the campaign: 'cpc', 'cpm', or 'cpa'string
costNoAd costnumber
bannerIdNoAdserver identifier for the ad banner (creative) being displayedstring
zoneIdNoAdserver identifier for the zone where the ad banner is locatedstring
advertiserIDNoAdserver identifier for the advertiser which the campaign belongs tostring
campaignIdNoAdserver identifier for the ad campaign which the banner belongs tostring

An example:

snowplow('trackAdClick',
targetUrl: 'http://www.example.com',
clickId: '12243253',
costModel: 'cpm',
cost: 2.5,
bannerId: '23',
zoneId: '7',
impressionId: '67965967893', // the same as in trackAdImpression
advertiserId: '201',
campaignId: '12'
);

Ad click events are implemented as Snowplow self describing events.Here is the JSON schema for an ad click event.

Conversion

Use the trackAdConversion method to track ad conversions. Here are the arguments it accepts:

NameRequired?DescriptionType
conversionIdNoIdentifier for the particular conversion instancestring
costModelNoThe cost model for the campaign: 'cpc', 'cpm', or 'cpa'string
costNoAd costnumber
categoryNoConversion categorynumber
actionNoThe type of user interaction, e.g. 'purchase'string
propertyNoDescribes the object of the conversionstring
initialValueNoHow much the conversion is initially worthnumber
advertiserIDNoAdserver identifier for the advertiser which the campaign belongs tostring
campaignIdNoAdserver identifier for the ad campaign which the banner belongs tostring
note

All properties are optional but you must specify at least one for this to be a valid call to trackAdConversion.

An example:

snowplow('trackAdConversion', {
conversionId: '743560297',
costModel: 'cpa',
cost: 10,
category: 'ecommerce',
action: 'purchase',
property: '',
initialValue: 99,
advertiserId: '201',
campaignId: '12'
});

Ad conversion events are implemented as Snowplow self describing events. Here is the schema for an ad conversion event.

Avoiding name collisions

It may be the case that multiple ads from the same source end up on a single page. If this happens, it is important that the different Snowplow code snippets associated with those ads not interfere with one another. The best way to prevent this is to randomly name each tracker instance you create so that the probability of a name collision is negligible. See Managing multiple trackers for more on having more than one tracker instance on a single page.

Below is an example of how to achieve this when using Snowplow ad impression tracking.

<!-- Snowplow starts plowing -->
<script type="text/javascript">

// Wrap script in a closure.
// This prevents rnd from becoming a global variable.
// So if multiple copies of the script are loaded on the same page,
// each instance of rnd will be inside its own namespace and will
// not overwrite any of the others.
// See http://benalman.com/news/2010/11/immediately-invoked-function-expression/
(function(){
// Randomly generate tracker namespace to prevent clashes
var rnd = Math.random().toString(36).substring(2);

// Load Snowplow
;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[];
p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments)
};p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1;
n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","{{URL to sp.js}}","snowplow"));

// Create a new tracker namespaced to rnd
snowplow('newTracker', rnd, '{{COLLECTOR_URL}}', {
appId: 'myApp',
});

// Replace the values below with macros from your adserver
snowplow('trackAdImpression:' + rnd, {
impressionId: '67965967893',
costModel: 'cpm', // 'cpa', 'cpc', or 'cpm'
cost: 5.5,
targetUrl: 'http://www.example.com',
bannerId: '23',
zoneId: '7',
advertiserId: '201',
campaignId: '12'
});
}());
</script>
<!-- Snowplow stops plowing -->

Even if several copies of the above script appear on a page, the trackers created will all (probably) have different names and so will not interfere with one another. The same technique should be used when tracking ad clicks.