Tracking data out-of-the-box
To track an event, the API is slightly different depending if you're using the JavaScript or Browser version of our web tracker.
For example, instrumenting a tracker and manually tracking a page view. Note that activity tracking (page pings) is also configured here.
- JavaScript (tag)
- Browser (npm)
<!-- Snowplow starts plowing -->
<script type="text/javascript">
;(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"));
snowplow('newTracker', 'sp', '{{collector_url_here}}', {
appId: 'my-app-id',
});
snowplow('enableActivityTracking', {
minimumVisitLength: 30,
heartbeatDelay: 10
});
snowplow('trackPageView');
</script>
<!-- Snowplow stops plowing -->
import {
newTracker,
trackPageView,
enableActivityTracking
} from '@snowplow/browser-tracker';
newTracker('sp', '{{collector_url_here}}', {
appId: 'my-app-id',
});
enableActivityTracking({
minimumVisitLength: 30,
heartbeatDelay: 10
});
trackPageView();
The tracker makes it easy to track different kinds of data. We provide three kinds of base events - PageViews, Structured, and fully custom (Self-Describing) - that can be manually tracked. On top of this, we also provide a range of plugins for automatic and manual tracking of different events and entities.
Each event has an associated context, which is composed of entities. The tracker attaches entities to the events based on the tracker configuration and active plugins. You can also attach your own custom entities to all trackX
method calls.
Tracker methods available through plugins do not necessarily support adding custom entities. For those please refer to the corresponding plugin documentation for details.
For example, here is a page view with an additional custom context entity.
- JavaScript (tag)
- Browser (npm)
snowplow('trackPageView', {
context: [{
schema: "iglu:com.example_company/page/jsonschema/1-2-1",
data: {
pageType: 'test',
lastUpdated: new Date(2021,04,01)
}
}]
});
trackPageView({
context: [{
schema: 'iglu:com.example_company/page/jsonschema/1-2-1',
data: {
pageType: 'test',
lastUpdated: new Date(2021,04,01)
}
}]
});
Every tracked event payload has a unique event_id
UUID string set by the tracker, a set of timestamps, and other ubiquitous properties such as the namespace
. You can find out more about how events and entities are structured here.
Auto-tracked entities
The tracker can be set up to automatically track certain events, or automatically add entities to every event sent. Most autotracking is specifically configured using plugins, which are imported, enabled, and configured individually.
However, the following autotracked context entities can be configured directly when instrumenting the tracker. To enable them, simply add their names and boolean to the contexts
field of the configuration object. They will be added to every event tracked.
Entity | Usage | Enabled by default |
---|---|---|
webPage | A UUID for the page view. | true |
session | Data about the current session. | false |
browser | Properties of the user's browser. | false |
The following context entities can be configured by plugin, or when setting up the JavaScript tracker configuration object only. To automatically track these context entities when using the Browser tracker, use the plugin versions.
Entity | Usage | Enabled by default |
---|---|---|
performanceTiming | Performance timing metrics. | true |
gaCookies | Extract GA cookie values. | true |
geolocation | User's geolocation. | false |
clientHints | Chrome user-agent Client Hints | true |
Manually-tracked events
The tracker provides methods for tracking different types of events. The events are divided into two groups: canonical events and self-describing events. Canonical event properties have their own column in the data warehouse, while self-describing custom events are based on JSON schema.
Page view
Read about page view tracking here.
Custom (self-describing)
Our philosophy in creating Snowplow is that users should capture important user interactions and design suitable data structures for this data capture. You can read more about that philosophy here.
Read about how to track custom events here.
Structured
There may be user interactions where custom self-describing events are too complex or unwarranted. They are candidates to track using trackStructEvent
.
There are five parameters that can be associated with each structured event. Only the first two are required:
Name | Required? | Description | Type |
---|---|---|---|
Category | Yes | The name you supply for the group of objects you want to track e.g. 'media', 'ecomm'. | String |
Action | Yes | Defines the type of user interaction for the web object e.g. 'play-video', add-to-basket'. | String |
Label | No | Identifies the specific object being actioned e.g. ID of the video being played, or the SKU or the product added to basket. | String? |
Property | No | Describing the object or the action performed on it. This might be the quantity of an item added to basket. | String? |
Value | No | Quantify or further describe the user action. This might be the price of an item added to basket, or the starting time of the video where play was just pressed. | Float? |
An example of tracking a user listening to a music mix:
- JavaScript (tag)
- Browser (npm)
snowplow('trackStructEvent', {
category: 'Mixes',
action: 'Play',
label: 'MrC/fabric-0503-mix',
property: '',
value: 0.0
});
import { trackStructEvent } from '@snowplow/browser-tracker';
trackStructEvent({
category: 'Mixes',
action: 'Play',
label: 'MrC/fabric-0503-mix',
value: 0.0
});
Tracking data that is not event-type specific
Some data, such as that relating to the user whose activity is being tracked, is relevant across all event types. The tracker provides two mechanisms for tracking this kind of data.
Certain properties, including domain_userid
or application_id
, can be set as "atomic" properties in the raw event. These properties have their own column in the data warehouse.
A more general and powerful method is to attach self-describing JSON "context entities" to your events - the same JSON schemas as used for self-describing events. This means that any data that can be described by a JSON schema can be added to any or all of your events. Read more here.
All events also provide the option for setting a custom timestamp, called trueTimestamp
. See below for details.
Setting application ID
Set the application ID using the appId
field of the tracker configuration object. This will be attached to every event the tracker fires. You can set different application IDs on different parts of your site. You can then distinguish events that occur on different applications by grouping results based on application_id
.
Setting application version
The option to track the application version was introduced in version 4.1 of the JavaScript tracker.
Set the application ID using the appVersion
field of the tracker configuration object. This will be attached to every event the tracker fires using the application context entity.
The version of can be a semver-like structure (e.g 1.1.0) or a Git commit SHA hash.
Setting application platform
Set the application platform using the platform
field of the tracker configuration object. This will be attached to every event the tracker fires. Its default value is “web”. For a list of supported platforms, please see the Snowplow Tracker Protocol.
Setting the user ID
The JavaScript Tracker automatically sets a domain_userid
based on a first party cookie. Read more about cookies here.
There are many situations, however, when you will want to identify a specific user using an ID generated by one of your business systems. To do this, you use one of the methods described in this section: setUserId
, setUserIdFromLocation
, setUserIdFromReferrer
, and setUserIdFromCookie
.
Typically, companies do this at points in the customer journey where users identify themselves e.g. if they log in.
This will only set the user ID on further events fired while the user is on this page; if you want events on another page to record this user ID too, you must call setUserId
on the other page as well.
setUserId
setUserId
is the simplest of the four methods. It sets the business user ID to a string of your choice:
- JavaScript (tag)
- Browser (npm)
snowplow('setUserId', 'joe.blogs@email.com');
setUserId('joe.blogs@email.com');
setUserId
can also be called using the alias identifyUser
.
setUserIdFromLocation
setUserIdFromLocation
lets you set the user ID based on a querystring field of your choice. For example, if the URL is http://www.mysite.com/home?id=user345
, then the following code would set the user ID to “user345”:
- JavaScript (tag)
- Browser (npm)
snowplow('setUserIdFromLocation', 'id');
setUserIdFromLocation('id');
setUserIdFromReferrer
setUserIdFromReferrer
functions in the same way as setUserIdFromLocation
, except that it uses the referrer querystring rather than the querystring of the current page.
- JavaScript (tag)
- Browser (npm)
snowplow('setUserIdFromReferrer', 'id');
setUserIdFromReferrer('id');
setUserIdFromCookie
Use setUserIdFromCookie
to set the value of a cookie as the user ID. For example, if you have a cookie called “cookieid” whose value is “user123”, the following code would set the user ID to “user123”:
- JavaScript (tag)
- Browser (npm)
snowplow('setUserIdFromCookie', 'cookieid');
setUserIdFromCookie('cookieid');
Getting user ID once set
It's possible to retrieve certain properties for use in your code, including the user ID, page view ID, and cookie values, using a tracker callback. This is an advanced usage of the tracker.
- JavaScript (tag)
- Browser (npm)
If you call snowplow
with a function as the argument, the function will be executed when sp.js loads:
snowplow(function () {
console.log("sp.js has loaded");
});
Or equivalently:
snowplow(function (x) {
console.log(x);
}, "sp.js has loaded");
The callback you provide is executed as a method on the internal trackerDictionary
object. This means that you can access the trackerDictionary
using this
.
// Configure a tracker instance named "sp"
snowplow('newTracker', 'sp', '{{COLLECTOR_URL}', {
appId: 'snowplowExampleApp'
});
// Access the tracker instance inside a callback
snowplow(function () {
var sp = this.sp;
var domainUserId = sp.getDomainUserId();
console.log(domainUserId);
})
The callback function should not be a method:
// TypeError: Illegal invocation
snowplow(console.log, "sp.js has loaded");
This will not work because the value of this
in the console.log
function will be the trackerDictionary
rather than console
.
You can get around this problem using Function.prototoype.bind
as follows:
snowplow(console.log.bind(console), "sp.js has loaded");
For more on execution context in JavaScript, see the MDN page.
When initialising a tracker, you can use the returned tracker
instance to access various properties from this tracker instance.
// Configure a tracker instance named "sp"
const sp = newTracker('sp', '{{COLLECTOR_URL}', {
appId: 'snowplowExampleApp'
});
// Access the tracker properties
const domainUserId = sp.getDomainUserId();
The getUserId
method returns the user ID which you configured using setUserId()
:
- JavaScript (tag)
- Browser (npm)
// Access the tracker instance inside a callback
snowplow(function () {
var sp = this.sp;
var userId = sp.getUserId();
console.log(userId);
})
const userId = sp.getUserId();
console.log(userId);
Setting a custom page URL and referrer URL
The Snowplow JavaScript Tracker automatically tracks the page URL and referrer URL on any event tracked. However, in certain situations, you may want to override the one or both of these URLs with a custom value. For example, this might be desirable if your CMS spits out particularly ugly URLs that are hard to unpick at analysis time.
To set a custom page URL, use the setCustomUrl
method:
- JavaScript (tag)
- Browser (npm)
snowplow('setCustomUrl', 'http://mysite.com/checkout-page');
setCustomUrl('http://mysite.com/checkout-page');
To set a custom referrer, use the setReferrerUrl
method:
- JavaScript (tag)
- Browser (npm)
snowplow('setReferrerUrl', 'http://custom-referrer.com');
setReferrerUrl('http://custom-referrer.com');
On an SPA, the page URL might change without the page being reloaded. Whenever an event is fired, the Tracker checks whether the page URL has changed since the last event. If it has, the page URL is updated and the URL at the time of the last event is used as the referrer. If you use setCustomUrl
, the page URL will no longer be updated in this way. Similarly if you use setReferrerUrl
, the referrer URL will no longer be updated in this way.
To use setCustomUrl
within an SPA, call it before all trackPageView
calls.
If you want to ensure that the original referrer is preserved even though your page URL can change without the page being reloaded, use setReferrerUrl
like this before sending any events:
- JavaScript (tag)
- Browser (npm)
snowplow('setReferrerUrl', document.referrer);
setReferrerUrl(document.referrer);
Adding custom timestamps to events
Snowplow events have several timestamps. The raw event payload always contains a deviceCreatedTimestamp
(dtm
) and a deviceSentTimestamp
(stm
). Other timestamps are added as the event moves through the pipeline.
Every trackX...()
method in the tracker allows for a custom timestamp, called trueTimestamp
to be set. Read more about timestamps in this still relevant forums post.
As standard, every event tracked by the Javascript tracker will be recorded with two timestamps:
- A
device_created_tstamp
- set when the event occurred - A
device_sent_tstamp
- set when the event was sent by the tracker to the collector
These are combined downstream in the Snowplow pipeline (with the collector_tstamp
) to calculate the derived_tstamp
, which is our best estimate of when the event actually occurred.
In certain circumstances you might want to set the timestamp yourself e.g. if the JS tracker is being used to process historical event data, rather than tracking the events live. In this case you can set the true_timestamp
for the event. When set, this will be used as the value in the derived_tstamp
rather than a combination of the device_created_tstamp
, device_sent_tstamp
and collector_tstamp
.
To set the true timestamp add an extra argument to your track method: {type: 'ttm', value: unixTimestampInMs}
.
E.g. to set a true timestamp with a page view event:
- JavaScript (tag)
- Browser (npm)
snowplow('trackPageView', {
timestamp: { type: 'ttm', value: 1361553733371 }
});
trackPageView({
timestamp: { type: 'ttm', value: 1361553733371 }
});
E.g. to set a true timestamp for a self-describing event:
- JavaScript (tag)
- Browser (npm)
snowplow('trackSelfDescribingEvent', {
event: {
schema: 'iglu:com.acme_company/viewed_product/jsonschema/2-0-0',
data: {
productId: 'ASO01043',
category: 'Dresses',
brand: 'ACME',
returning: true,
price: 49.95,
sizes: ['xs', 's', 'l', 'xl', 'xxl'],
availableSince: new Date(2013,3,7)
}
},
timestamp: { type: 'ttm', value: 1361553733371 }
});
trackSelfDescribingEvent({
event: {
schema: 'iglu:com.acme_company/viewed_product/jsonschema/2-0-0',
data: {
productId: 'ASO01043',
category: 'Dresses',
brand: 'ACME',
returning: true,
price: 49.95,
sizes: ['xs', 's', 'l', 'xl', 'xxl'],
availableSince: new Date(2013,3,7)
}
},
timestamp: { type: 'ttm', value: 1361553733371 }
});