This blog post will cover the following changes:
- Changes to the Snowplow API
- New feature: tracker namespacing
- New feature: link click tracking
- New feature: ad tracking
- New feature: offline tracking
- Self-describing JSONs
- Functional tests
- Other improvements
- Documentation and getting help
1. Changes to the Snowplow API
Load sp.js using the following script:
You can replace
If you believe there could be another copy of Snowplow running on a given website, rename the Snowplow function to something unique, to guarantee that there won’t be a conflict between the two copies. This is particularly important for widget, advertising and analytics companies using Snowplow – because your customers may be using Snowplow themselves.
2. New feature: tracker namespacing
New in version 2.0.0 is the ability to have multiple trackers running at once. This is useful if you want to log events to more than one collector – for example, you could send events to both our tried-and-tested CloudFront Collector and our experimental Scala Stream Collector. You can even choose which trackers fire which events.
To initialize a new tracker, use the newly-introduced method
It constructs a new tracker based on three arguments: the name of the new tracker, the endpoint to which events should be logged, and an “argmap” of optional settings. An example:
This creates two trackers called “primary” and “secondary” logging events to different Cloudfront subdomains. (Note that the full string
"d3rkrsqld9gmqf.cloudfront.net" must be used instead of just
"d3rkrsqld9gmqf"). Events logged by the primary tracker will not be Base64-encoded; events logged by the secondary tracker will be. Both trackers use the same cookie name. If you do not set a cookie name, the default
'_sp_' will be used. Setting a custom cookie name is recommended, as it prevents conflicts when two Snowplow users on the same web page attempt to read and write the same cookie.
You can specify which tracker or trackers should execute a method by appending their names to the end of the method name, separating the two with a colon. To only have the primary tracker track a page view event:
To have more than one tracker execute a method, separate the tracker names with semicolons:
If you do not provide a list of tracker namespaces when calling a method, every tracker that you have created will execute that method.
The name of the tracker that fired an event will always be added to the querystring in a newfield,
3. New feature: link click tracking
Note: Link click tracking is implemented using the new self-describing JSON format for unstructured events. Loading link clicks into Redshift will depend on Snowplow 0.9.5, coming soon.
You can now track link click events using
enableLinkClickTracking. This method only needs to be called once. Then whenever a link is clicked, a link click event will automatically be fired. The event will include the link element’s CSS id and classes, as well as the destination URL.
The JSON Schema for a link click is available on Iglu Central.
Here is the method’s signature:
Use it like this to turn on click tracking for every link:
criterion argument lets you fine-tune which links you want to be tracked with either a whitelist, a blacklist, or a filter function.
A blacklist is an array of CSS class names for links which should not be tracked. For example, the below code will stop link click events firing for links with the class “barred” or “untracked”, but will fire link click events for all other links:
If there is only one class name you wish to blacklist, it doesn’t have to be in an array:
A whitelist is the opposite of a blacklist. With this option, only clicks on links belonging to one of the whitelisted classes will be tracked.
If there is only one class name you wish to whitelist, it doesn’t have to be in an array:
Finally, if neither of the above options provides finegrained-enough control, you can use a filter function instead. It should take one argument, the link element, and return either
true (in which case clicks on the link will be tracked) or
false (in which case they won’t be).
The following code will enable click tracking for those and only those links which have an
pseudoClicks argument can be used to turn on pseudo-click tracking, which listens not for click events but for successive mouseup and mousedown events over the same link. This is useful because some browsers, including Firefox, do not generate click events for the middle mouse button.
Use `enableLinkClickTracking like this:
You can also use the
trackLinkClick method to manually track a single link click:
Use it like this:
Finally, if you add links to the document after calling
refreshLinkClick tracking to add click tracking to all new links which meet any criterion you have already set up using
4. New feature: ad tracking
This release adds three new ad tracking functions:
trackAdConversion. Each of these fires a dedicated unstructured event. Here are their function signatures:
The JSON Schemas for these new events are all available on Iglu Central:
trackAdClick on the page where your ad is served, and
trackAdConversion on the page(s) where users convert.
For an example of all three functions in action on a page with three distinct ads, see this file.
5. New feature: offline tracking
Thanks to community member Ryan Sorensen’s contribution, events fired while a user is offline are no longer lost forever. If the Tracker detects that an event has not successfully reached the collector due to the user being offline, the event will be added to a queue and will be sent once connectivity has been restored. The queue is held in browser Local Storage so that the unsent events can be remembered even after the leaving the page.
6. Self-describing JSONs
Note: The new self-describing JSON format for unstructured events relies on Snowplow 0.9.5, coming soon.
Snowplow unstructured events and custom contexts are now defined using JSON schema, and should be passed to the Tracker using self-describing JSONs. Here is an example of the new format for unstructured events:
data field contains the actual properties of the event and the
schema field of the JSON points to the JSON schema against which the contents of the
data field should be validated. The
data field should be flat, rather than nested. The user who sent in the above event would need to have defined a schema for a
viewed_product event. The schema would probably describe which fields the JSON can contain, which of those fields are required and which are optional, and the type of data found in each field.
Custom contexts work similarly. Since an event can have multiple contexts attached, the
contexts argument of each
trackXXX method must be a array:
Note that if the
contexts argument is provided, it cannot be an empty array.
This example shows a page view event with two custom contexts attached: one describing the page using schema.org’s WebPage schema, and another describing the user.
7. Functional tests
We have expanded our test suite to include functional tests for our helpers.js and detectors.js modules, run using Sauce Labs. The results of the the tests for different
browser / OS combinations can be seen in the new “Testing” section of the README.
8. Other improvements
We have also:
- Moved fixUpUrl, our proxy detection function, into its own file, lib/proxies.js #112
- Fixed the duplication of the querystring parameter lookup function #111
- Started rigorously checking whether a page is cached by Yahoo #142
- Replaced cookie.js with an external module, browser-cookie-lite #88
- Removed references to the legacy referrer cookie #118
- Fixed the warnings generated by the Closure Compiler, thanks @steve-gh! #170
- Upgraded Intern to version 1.5.0 #119
- Fixed the link in the code climate button in the README #149
- Deleted the obsolete example file ads/sync.html #182
The upgraded minified tracker is available here:
10. Documentation and getting help
Check out the v2.0.0 release page on GitHub for the full list of changes made in this version.
As always, if you run into any issues or don’t understand any of the above changes, please raise an issue or get in touch with us via the usual channels.