Google AMP (1.1.0)
Overviewโ
Snowplow is collaborating with Google on their Accelerated Mobile Pages Project (AMPP or AMP for short). AMP is an open source (Apache License 2.0) initiative to improve the mobile web experience by optimizing web pages for mobile devices.
To learn more about analytics for AMP pages see the amp-analytics reference. For general information about AMP see What Is AMP? on the Accelerated Mobile Pages (AMP) Project site.
Snowplow is natively integrated into the project, so pages optimized with AMP HTML can be tracked in Snowplow by adding the appropriate amp-analytics
tag to your pages:
<body>
...
<amp-analytics type="snowplow_v2" id="snowplow_v2">
<script type="application/json">
{
"vars": {
"collectorHost": "collector.snplow.net",
"appId": "amp-examples-v2.0.2",
...
},
"linkers": {
"enabled": true,
...
},
"triggers": {
"defaultPageview": {
"on": "visible",
"request": "pageView"
}
}
}
</script>
</amp-analytics>
</body>
The tracker utilises AMP linker functionality to ensure that user identification can be done where a user may visit via the google domain or the site's own domain. In order to function, this requires that linkers are enabled in the amp-analytics configuration. Not doing so can result in changing AMP client Ids (which are the primary user identifier).
Standard variablesโ
collectorHost
and appId
must be provided in the "vars"
section of the tag:
"vars": {
...
},
The rest are optional
collectorHost
โ
Specify the host to your collector like so:
"vars": {
"collectorHost": "snowplow-collector.acme.com",
...
Notes:
- Do not include the protocol aka schema (
http(s)://
) - Do not include a trailing slash
- Use of HTTPS is mandatory in AMP, so your Snowplow collector must support HTTPS
appId
โ
You must set the application ID for the website you are tracking via AMP:
"vars": {
"appId": "campaign-microsite",
...
Notes:
- You do not have to use the
appId
to distinguish AMP traffic from other web traffic (unless you want to) - see the Analytics section for an alternative approach.
userId
โ
Specify the optional "userId"
var to set the uid/user_id Snowplow Tracker Protocol field.
"vars": {
"userId": "someUserId",
...
nameTracker
โ
Specify the optional "nameTracker" var to set the tna/name_tracker Snowplow Tracker Protocol field.
"vars": {
"nameTracker": "someTrackerName",
...
customContexts
โ
Custom contexts may be added by including Self-Describing JSON as a "customContexts"
var, with "
characters escaped:
"vars": {
"customContexts": "{\"schema\":\"iglu:com.acme/first_context/jsonschema/1-0-0\",\"data\":{\"someKey\":\"someValue\"}}"
...
Multiple custom contexts may be added by separating each self-describing JSON with a comma:
"vars": {
"customContexts": "{\"schema\":\"iglu:com.acme/first_context/jsonschema/1-0-0\",\"data\":{\"someKey\":\"someValue\"}},{\"schema\":\"iglu:com.acme/second_context/jsonschema/1-0-0\",\"data\":{\"someOtherKey\":\"someOtherValue\"}}"
...
Custom contexts may either be set globally for all events (as a top-level var, see above) or per-event trigger:
...
"triggers": {
...
"defaultPageview": {
"on": "click",
"selector": "visible",
"request": "pageView",
"vars": {
"customContexts": "{\"schema\":\"iglu:com.acme/first_context/jsonschema/1-0-0\",\"data\":{\"someKey\":\"someValue\"}}"
}
}
}
...
These approaches may not currently be mixed, however.
Tracking eventsโ
The following trigger request values are supported for the Snowplow Analytics configuration:
pageView
for page view trackingstructEvent
for structured event trackingampPagePing
for page ping trackingselfDescribingEvent
for custom event tracking
All event tracking is disabled by default; you can enable it on an event-by-event basis as follows:
Page viewโ
Enable the page view tracking like so:
<amp-analytics type="snowplow_v2" id="event1">
<script type="application/json">
{
"vars": {
"collectorHost": "snowplow-collector.acme.com", // Replace with your collector host
"appId": "campaign-microsite" // Replace with your app ID
},
"triggers": {
"trackPageview": { // Trigger names can be any string. trackPageview is not a required name
"on": "visible",
"request": "pageView"
}
}
}
</script>
</amp-analytics>
Structured eventsโ
Structured events are user interactions with content that can be tracked independently from a web page or a screen load. "Structured" refers to the Google Analytics-style structure of having up to five fields (with only the first two required).
Events can be sent by setting the AMP trigger request value to event and setting the required event category and action fields.
The following example uses the selector attribute of the trigger to send an event when a particular element is clicked:
<amp-analytics type="snowplow_v2" id="event2">
<script type="application/json">
{
"vars": {
"collectorHost": "snowplow-collector.acme.com", // Replace with your collector host
"appId": "campaign-microsite" // Replace with your app ID
},
"triggers": {
"trackClickOnHeader" : {
"on": "click",
"selector": "#header",
"request": "structEvent",
"vars": {
"structEventCategory": "ui-components",
"structEventAction": "header-click"
}
}
}
}
</script>
</amp-analytics>
You can set key-value pairs for the following event fields in the vars attribute of the trigger:
Argument | Description | Required? | Validation |
---|---|---|---|
structEventCategory | The grouping of structured events which this action belongs to | Yes | String |
structEventAction | Defines the type of user interaction which this event involves | Yes | String |
structEventLabel | A string to provide additional dimensions to the event data | No | String |
structEventProperty | A string describing the object or the action performed on it | No | String |
structEventValue | A value to provide numerical data about the event | No | Int or Float |
Page pingsโ
Enable page ping tracking like so:
<amp-analytics type="snowplow_v2" id="event3">
<script type="application/json">
{
"vars": {
"collectorHost": "snowplow-collector.acme.com", // Replace with your collector host
"appId": "campaign-microsite" // Replace with your app ID
},
"triggers": {
"trackPagePings": {
"on": "timer",
"request": "ampPagePing",
"timerSpec": {
"interval": 30, // Set to desired ping interval
"maxTimerLength": 1800,
"immediate": false,
"startSpec": {
"on": "visible",
"selector": ":root"
},
"stopSpec": {
"on": "hidden",
"selector": ":root"
}
}
}
}
}
</script>
</amp-analytics>
AMP page ping events will be sent as AMP-specific page ping events (rather than Javascript tracker page pings), against the AMP page ping schema, since the data available on AMP is defined differently to Javascript tracker page pings.
All events are sent with an AMP web page context, for aggregation of pings by page view id.
Custom eventsโ
Custom events may be sent via the AMP tracker by passing the schema vendor, and version, and an escaped JSON of the desired data, as follows:
<amp-analytics type="snowplow_v2" id="event3">
<script type="application/json">
{
"vars": {
"collectorHost": "snowplow-collector.acme.com", // Replace with your collector host
"appId": "campaign-microsite" // Replace with your app ID
},
"triggers": {
"trackSelfDescribingEvent": {
"on": "click",
"selector": "a",
"request": "selfDescribingEvent",
"vars": {
"customEventSchemaVendor": "com.snowplowanalytics.snowplow",
"customEventSchemaName": "link_click",
"customEventSchemaVersion": "1-0-1",
"customEventSchemaData": "{\"targetUrl\":\"${targetUrl}\",\"elementId\":\"TEST\",\"elementContent\":\"${elementContent}\"}"
}
}
}
}
</script>
</amp-analytics>
Analyticsโ
v2 of the tracker brings with it significant improvements in our ability to model and gain insights.
Standard fieldsโ
All events sent via this tracker will have:
v_tracker
set toamp-1.1.0
platform
set toweb
If you want to analyze events sent via this tracker, you may prefer to query for v_tracker LIKE 'amp-%'
to future-proof your query against future releases of this tracker (which may change the version number).
Page view and ping aggregationโ
By default, the AMP web page context is attached to every event. This will contain the AMP-defined PAGE_VIEW_ID_64, which defined as "intended to be random with a high entropy and likely to be unique per URL, user and day".
Users can aggregate page views, page pings and other events on-page by this ID to aggregate engaged time, and model events to a page view level, by combining it with the url, amp client ID, and date.
Note that page pings and the page view ID itself are not defined by Snowplow's logic, but by what's made available by AMP - therefore applying the same logic to this data as that produced by the Javascript tracker is liable to produce different results.
Session informationโ
Available from version 1.1.0.
By default the AMP Session context is attached to every event. This context allows for tracking information related to session analytics capabilities, as implemented in the AMP framework. The attributes included are the following:
ampSessionId
: An identifier for the AMP session.ampSessionIndex
: The index of the current session for this user.sessionEngaged
: If there has been any kind of user engagement in the AMP session. Engagement in this context means if the page is visible, has focus and is in the foreground.sessionCreationTimestamp
: Timestamp at which the session was created in milliseconds elapsed since the UNIX epoch.lastSessionEventTimestamp
: Timestamp at which the last event took place in the session in milliseconds elapsed since the UNIX epoch.
User Identificationโ
By default, the AMP ID context is attached to every event. This contains the AMP Client ID, the user_id
(if set via the userId
var), and the domain_userid (if passed to an AMP page via cross-domain linking - more detail below).
This provides a map between the main relevant identifiers, which can be used to model user journeys across platforms. Users can choose to instrument further user identification methods using custom contexts.
In order for the AMP Client ID to behave as expected, the 'linker' parameter of the configuration JSON must have 'enabled': true
set. Failing to do so can result in changing AMP client IDs, even where a user remains on AMP pages for the whole journey. (This can happen because AMP pages can be served from Google's AMP cache).
The tracker is designed to handle user journeys as follows:
JS-tracker page to AMP pageโ
Where a user moves from a standard web page, tracked by the Javascript tracker, to an AMP page, the domain userid from the Javascript tracker can be passed to the AMP tracker by enabling the Javascript tracker's crossDomainLinker. The AMP tracker will parse the value from the querystring, and attach it to all events, along with the AMP client ID, via the AMP ID context.
The AMP tracker uses a combination of cookies and the AMP linker to attempt to retain the value, however due to the nature of AMP pages, there is no guarantee that the value will be retained across sessions. To ensure best possible retention of the value within the session, make sure the tracker config has linker pages enabled for your AMP domains:
...
"linkers": {
"enabled": true,
"proxyOnly": false,
"destinationDomains": ["ampdomain"]
},
...
Data models should be designed for an 'at least once' identification structure - in other words, configuring the cross-domain linker correcttly will ensure at least one event contains both AMP ID and domain User ID. Models should aim to map this across all events. Of course, this method of identification depends on the user traveling directly from a JS-tracked page to an AMP page at least once.
AMP page to JS-tracker pageโ
Where a user moves frrom an AMP page to a standard web page which is tracked by the Javascript tracker, the AMP tracker will use AMP's linker functionality to append the AMP CLient ID to the querystring, as long as linkers are enabled for the destination domain:
...
"linkers": {
"enabled": true,
"proxyOnly": false,
"destinationDomains": ["destDomain"]
},
...
This will add a querystring parameter 'linker=' to the destination url, which contains the amp_id value, base-64 encoded. This will look something like this: ?sp_amp_linker=1*1c1wx43*amp_id*amp-a1b23cDEfGhIjkl4mnoPqr
.
The structure of this param is explained in the AMP documentation - models can extract the base64-encoded AMP Client ID, decode it, and map it to the domain userid (or any other user value) from the Javascript tracker.
Reporting Issues and Contributingโ
A fork of the AMP project can be found in the Snowplow Incubator Github Repo. Please submit issues, bugreports and PRs to this repo.