Migrating from v3 to v4
Version 4 is a major release with several breaking changes to defaults and behavior. We have tried to keep the APIs compatible with v3 where possible to reduce code changes required.
These code snippets are for the Javascript (tag) tracker, but the same changes apply for the Browser (npm) tracker.
Behavior changes​
cookieDomain
and discoverRootDomain
handling​
discoverRootDomain
is a setting to enable automatic detection of the closest-to-root domain possible to set cookies on.
This is important to allow consistent Domain User ID and Domain Session ID values between pages on different subdomains of the same domain.
Without this setting, the root domain value needs to be set explicitly with the cookieDomain
setting in order to be shared correctly between subdomains.
If neither are set, the cookie gets set against the current domain of the page and is not shared between any other subdomains.
In earlier versions, discoverRootDomain
was disabled by default.
Enabling the setting caused the SDK to ignore any configured cookieDomain
and prefer the discoverRootDomain
-derived value instead.
In v4, discoverRootDomain
is now enabled by default, but will defer to the value in cookieDomain
if it is set.
This means previously correct configurations may now use the incorrect domain for updating cookies, and you may need to update your newTracker
code to account for this change.
- If you previously had
discoverRootDomain: true
, you can now remove this setting and should remove anycookieDomain
configuration. - If you previously had
cookieDomain
configured and notdiscoverRootDomain
, no change is required. - If you previously had neither
cookieDomain
nordiscoverRootDomain
set, you will need to adddiscoverRootDomain: false
to maintain the previous behavior.
- JavaScript (v3)
- JavaScript (v4)
// v3: ignored cookieDomain, always used discoverRootDomain
window.snowplow('newTracker', 'sp', {
cookieDomain: 'example.com',
discoverRootDomain: true,
});
// v3: explicit cookieDomain, discoverRootDomain disabled
window.snowplow('newTracker', 'sp', {
cookieDomain: 'example.com',
discoverRootDomain: false, // or not set
});
// v3: no domain config
window.snowplow('newTracker', 'sp', {});
// v4: remove cookieDomain, use default discoverRootDomain
window.snowplow('newTracker', 'sp', {});
// v4: explicit cookieDomain, preferred over discoverRootDomain
window.snowplow('newTracker', 'sp', {
cookieDomain: 'example.com',
});
// v4: for no domain, explicitly opt-out of discoverRootDomain
window.snowplow('newTracker', 'sp', {
discoverRootDomain: false,
});
Async cookie access​
Whereas in v3, the tracker updated user and session information in cookies during the track call (e.g., trackPageView
), v4 makes this asynchronous.
The cookies are updated within 10ms of the track call and the read cookie values are cached for 50ms.
This strategy makes the track function take less time and avoid blocking the main thread of the app.
There is an option to keep the behavior from v3 and update cookies synchronously. This can be useful for testing purposes to ensure that the cookies are written before the test continues. It also has the benefit of making sure that the cookie is correctly set before session information is used in events. The downside is that it is slower and blocks the main thread.
Read more about the synchronous cookie write option.
Removed Beacon API, introduced keepalive
​
Version 4 removes the option to set beacon
as the method for making requests to the Snowplow Collector.
This is due to the use of the fetch API instead of the XMLHttpRequest API for making HTTP requests.
As an alternative to the Beacon API, there is a new keepalive option available from the fetch API. It indicates that the request should be allowed to outlive the webpage that initiated it. It enables requests to the Snowplow Collector to complete even if the page is closed or navigated away from.
Read more about the option here.
credentials
instead of withCredentials
​
Also related to the move to fetch instead of XMLHttpRequest, we have changed the withCredentials
configuration option.
It is now called credentials
and has values that reflect the option in the fetch API.
Read more about the option here..
os_timezone
detection​
The JavaScript and Browser trackers will now attempt to populate the os_timezone
field by querying the Intl.DateTimeFormat
API in supported browsers.
Previously, this value was populated by heuristics in the Timezone plugin.
The new method may produce different results and only supports more modern browsers.
The Timezone plugin is still supported, but no longer bundled in sp.js
by default.
Using the plugin will override the new default value.
Default for encodeBase64
​
The encodeBase64
setting controls whether self describing JSON data in entities and self describing events are encoded with URL-safe base64 encoding or as JSON strings.
When sending events via the GET
method, this is recommended because the JSON string would require URL-encoding to safely transmit, which typically results in a larger payload than with the ~33% size overhead of base64-encoded JSON data, which is inherently URL-safe.
For POST
requests however, the overhead of base64 encoding makes the payload size larger and makes debugging more difficult as the payload isn't human-readable, and has no safety benefits.
For example:
/* Actual JSON, length = 211 */
{"schema":"iglu:com.snowplowanalytics.snowplow/contexts/jsonschema/1-0-0","data":[{"schema":"iglu:com.snowplowanalytics.snowplow/web_page/jsonschema/1-0-0","data":{"id":"0edd614e-975d-4f3a-9cd9-af123ac35068"}}]}
/* URI-encoded JSON, length = 289 */
"%7B%22schema%22%3A%22iglu%3Acom.snowplowanalytics.snowplow%2Fcontexts%2Fjsonschema%2F1-0-0%22%2C%22data%22%3A%5B%7B%22schema%22%3A%22iglu%3Acom.snowplowanalytics.snowplow%2Fweb_page%2Fjsonschema%2F1-0-0%22%2C%22data%22%3A%7B%22id%22%3A%220edd614e-975d-4f3a-9cd9-af123ac35068%22%7D%7D%5D%7D"
/* Base64-encoded JSON, length = 282 */
"eyJzY2hlbWEiOiJpZ2x1OmNvbS5zbm93cGxvd2FuYWx5dGljcy5zbm93cGxvdy9jb250ZXh0cy9qc29uc2NoZW1hLzEtMC0wIiwiZGF0YSI6W3sic2NoZW1hIjoiaWdsdTpjb20uc25vd3Bsb3dhbmFseXRpY3Muc25vd3Bsb3cvd2ViX3BhZ2UvanNvbnNjaGVtYS8xLTAtMCIsImRhdGEiOnsiaWQiOiIwZWRkNjE0ZS05NzVkLTRmM2EtOWNkOS1hZjEyM2FjMzUwNjgifX1dfQ"
/* JSON-string-encoded JSON, length = 229 */
"{\"schema\":\"iglu:com.snowplowanalytics.snowplow/contexts/jsonschema/1-0-0\",\"data\":[{\"schema\":\"iglu:com.snowplowanalytics.snowplow/web_page/jsonschema/1-0-0\",\"data\":{\"id\":\"0edd614e-975d-4f3a-9cd9-af123ac35068\"}}]}"
In v3, encodeBase64
defaulted to true
if not explicitly configured.
In v4, if not configured explicitly, the setting will now default to false
if the eventMethod
is post
(the default), but remains true
if using the get
method.
If your Collector is hosted behind a Web Application Firewall and custom entities/events include content that may be classified as risky (e.g. content containing HTML code) this may trigger false positives and cause the events to be rejected by the firewall; re-enabling base64 encoding should obfuscate the payload again and allow successful delivery.
Per the tracker protocol, the payload fields used for base-64-encoded data differs from plain JSON-encoded data: when upgrading to v4, plugins or tests relying on payload data being in cx
or ue_px
may now require updating to check the non-base64-encoded equivalents in co
and ue_pr
. Tracker protocol-compliant processors such as the Enricher should already support both fields and require no changes.
Dropped support for older browsers​
The support for the following browsers versions has been dropped:
- Drop IE 11 and Safari 10 support.
Plugin changes​
Plugin APIs are forwards compatible with v3 plugins, so the plugins that are no longer maintained can still be used with v4 if required.
v4 plugins that don't use the new filter
API are also backwards compatible with v3 if you only need some of the new functionality.
Removed plugins​
The following plugins are no longer maintained and are no longer available in v4. The v3 plugins should still work with v4, but will no longer be officially supported.
Bundled plugin changes​
The list of plugins included in the default sp.js
JavaScript Tracker bundle has changed.
The following plugins are no longer included by default:
- Client Hints
- Classic Consent
- Classic Ecommerce
- Enhanced Ecommerce
- Timezone Detection
- Optimizely
- Optimizely X
- Performance Timing
The following plugins are now included by default:
To keep using old plugins, they will have to be explicitly installed using addPlugins
or built into a custom bundle.
Plugin behavior updates​
Button click​
- The plugin now uses
capture
-phase event listeners; button clicks that were previously untracked due to ancestor elements stopping event propagation are now more likely to track correctly - Buttons within Custom Components and open-mode shadow trees should now be trackable but were previously ignored
Form tracking​
- The plugin now uses document-level event listeners rather than per-element event listeners
- Because of the above, re-calling
enableFormTracking
is no longer required to detect forms dynamically added to the page - The plugin now uses
capture
-phase event listeners; previously it relied ontarget
orbubble
-phase events - Forms within Custom Components and open-mode shadow trees should now be trackable but were previously ignored; field focus must first occur before
change
andsubmit
can be detected correctly - Field transform functions can now return
null
values
GA cookies​
- The GA Cookies plugin now tracks in GA4 mode rather than Universal Analytics mode. This involves a different schema; the newer GA4 schema (
com.google.ga4/cookies
) is now the default, rather than the classic/Universal Analytics schema (com.google.analytics/cookies
). - To restore the old behavior, specify configuration for the plugin to enable UA support and disable GA4 support.
HTML5 media​
- Plugin now wraps the Snowplow Media plugin, uses v2 Media Tracking schemas
- The v3
enableMediaTracking
method has been removed, in its place isstartHtml5MediaTracking
- Media tracking can now be stopped with the
endHtml5Tracking
method
Link click​
- The plugin now uses document-level event listeners rather than per-element event listeners
- Because of the above,
refreshLinkClickTracking
is no longer required, is deprecated, and has no effect; new links will be tracked automatically - The plugin now uses
capture
-phase event listeners; previously it relied ontarget
orbubble
-phase events - Links within Custom Components and open-mode shadow trees should now be trackable but were previously ignored
- The manual
trackLinkClick
method can now accept an element to build a payload from, rather than requiring the called to construct the event payload - Link click tracking now also tracks links with empty
href
attributes and assignsabout:invalid
as thetargetUrl
to avoid the event failing schema validation. Such links will also be reported as warnings in the console.
YouTube media​
- Plugin now wraps the Snowplow Media plugin, uses v2 Media Tracking schemas
- New
startYouTubeTracking
andendYouTubeTracking
methods to align with existing v2 plugins enableYouTubeTracking
now wrapsstartYouTubeTracking
for v3 compatibility; a newdisableYouTubeTracking
method exists as an equivalent forendYouTubeTracking
- The new events use new schemas, continue using v3 to maintain consistent tracking
- The plugin should now work correctly alongside other users of the iFrame API