Skip to main content

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.

note

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 any cookieDomain configuration.
  • If you previously had cookieDomain configured and not discoverRootDomain, no change is required.
  • If you previously had neither cookieDomain nor discoverRootDomain set, you will need to add discoverRootDomain: false to maintain the previous behavior.
// 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', {});

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:

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 on target or bubble-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 and submit 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 is startHtml5MediaTracking
  • Media tracking can now be stopped with the endHtml5Tracking method
  • 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 on target or bubble-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 assigns about:invalid as the targetUrl 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 and endYouTubeTracking methods to align with existing v2 plugins
  • enableYouTubeTracking now wraps startYouTubeTracking for v3 compatibility; a new disableYouTubeTracking method exists as an equivalent for endYouTubeTracking
  • 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