JavaScript SDK v3

Send data to your destinations with the RudderStack JavaScript SDK v3.

The latest SDK v3 is written in TypeScript and is a lightweight, efficient, and optimized version of the RudderStack JavaScript SDK.

Some benefits of using this SDK are:

  • Smaller SDK of around 25KB (size reduction of approximately 30% from the previous version).
  • Fast, reliable, and less vulnerable to adblockers.
  • Ability to choose the required SDK features via plugins.
  • Lightweight storage data footprint with improved encryption technique.

This guide lists the new features, installation and load options, and plugins introduced in the SDK.

info
See Breaking changes before you start using the v3 SDK.

NPM Badge

Install SDK

You can install the JavaScript SDK v3 via a CDN or using NPM.

info
See SDK v3 migration guide if you are migrating your SDK to JavaScript SDK v3.

Using CDN

To install the JavaScript SDK v3 using CDN, you can use either the minified or non-minified snippet:

Minified

!function(){"use strict";var sdkBaseUrl="https://cdn.rudderlabs.com/beta/3.0.0-beta";var sdkName="rsa.min.js"
;var asyncScript=true;window.rudderAnalyticsBuildType="legacy",window.rudderanalytics=[]
;var e=["setDefaultInstanceKey","load","ready","page","track","identify","alias","group","reset","setAnonymousId","startSession","endSession"]
;for(var n=0;n<e.length;n++){var d=e[n];window.rudderanalytics[d]=function(e){return function(){
window.rudderanalytics.push([e].concat(Array.prototype.slice.call(arguments)))}}(d)}try{
new Function('return import("")'),window.rudderAnalyticsBuildType="modern"}catch(a){}
if(window.rudderAnalyticsMount=function(){var e=document.createElement("script")
;e.src="".concat(sdkBaseUrl,"/").concat(window.rudderAnalyticsBuildType,"/").concat(sdkName),e.async=asyncScript,
document.head?document.head.appendChild(e):document.body.appendChild(e)},"undefined"==typeof Promise){
var t=document.createElement("script")
;t.src="https://polyfill.io/v3/polyfill.min.js?features=globalThis%2CPromise&callback=rudderAnalyticsMount",
t.async=asyncScript,document.head?document.head.appendChild(t):document.body.appendChild(t)}else{
window.rudderAnalyticsMount()}window.rudderanalytics.load("<write-key>","<data-plane-url>",{})}();

Non-minified

(function() {
  "use strict";
  var sdkBaseUrl = "https://cdn.rudderlabs.com/beta/3.0.0-beta";
  var sdkName = "rsa.min.js";
  var asyncScript = true;
  window.rudderAnalyticsBuildType = "legacy";
  window.rudderanalytics = [];
  var methods = [ "setDefaultInstanceKey", "load", "ready", "page", "track", "identify", "alias", "group", "reset", "setAnonymousId", "startSession", "endSession"];
  for (var i = 0; i < methods.length; i++) {
    var method = methods[i];
    window.rudderanalytics[method] = function(methodName) {
      return function() {
        window.rudderanalytics.push([ methodName ].concat(Array.prototype.slice.call(arguments)));
      };
    }(method);
  }
  try {
    new Function('return import("")');
    window.rudderAnalyticsBuildType = "modern";
  } catch (e) {}
  window.rudderAnalyticsMount = function() {
    var rudderAnalyticsScript = document.createElement("script");
    rudderAnalyticsScript.src = "".concat(sdkBaseUrl, "/").concat(window.rudderAnalyticsBuildType, "/").concat(sdkName);
    rudderAnalyticsScript.async = asyncScript;
    if (document.head) {
      document.head.appendChild(rudderAnalyticsScript);
    } else {
      document.body.appendChild(rudderAnalyticsScript);
    }
  };
  if (typeof Promise === "undefined") {
    var rudderAnalyticsPromisesScript = document.createElement("script");
    rudderAnalyticsPromisesScript.src = "https://polyfill.io/v3/polyfill.min.js?features=globalThis%2CPromise&callback=rudderAnalyticsMount";
    rudderAnalyticsPromisesScript.async = asyncScript;
    if (document.head) {
      document.head.appendChild(rudderAnalyticsPromisesScript);
    } else {
      document.body.appendChild(rudderAnalyticsPromisesScript);
    }
  } else {
    window.rudderAnalyticsMount();
  }
  var loadOptions = {};
  window.rudderanalytics.load("<write-key>", "<data-plane-url>", loadOptions);
})();
info

Note that:

Installation workflow

The installation code snippets listed above perform the following actions:

  1. Based on browser capabilities, load either the legacy or modern bundle.
  2. Load Polyfill for Promise, if required, as it is necessary for the SDK to start up.
  3. Create an array to store the events until the rudderanalytics object is ready.
  4. Store the following methods to replay them when the rudderanalytics object is ready:
MethodDescription
load()Loads the SDK with the specified write keyThe write key (or source write key) is a unique identifier for your source. RudderStack uses this key to send events from a source to the specified destination. .
track()Tracks user events along with the associated properties.
identify()Identifies the users, records their traits, and associates them with their actions.
alias()Maps new user ID with an old ID.
group()Links an identified user with a group like a company, organization, or an account.
ready()Fired when the SDK has initialized itself and the other third-party native SDK destinations.
reset()Resets information related to the previously identified user.
setAnonymousIdSets the anonymousId.
startSessionStarts a new session. See Manual Session Tracking for more information.
endSessionClears the sessionId and ends the current session.
  1. Load the rudderanalytics object with the specified write key.
  2. Make a page()call to track the page views. It captures the whole URL including the UTM parameters as part of the page call payload, such as path, referrer, search, title, and URL. See page to override these properties.

Using NPM

While using the above snippets to integrate the JavaScript SDK with your website is recommended, you can alternatively use the NPM module for packaging RudderStack directly into your project.

To install the JavaScript SDK via NPM, run the following command:

npm install @rudderstack/analytics-js --save
warning
  • Use this NPM module only for browser installation. See Node.js SDK documentation to integrate RudderStack with your Node.js apps.
  • If you are using the Next.js framework, update your SDK imports from @rudderstack/analytics-js to @rudderstack/analytics-js/bundled to avoid any issues.

Since the NPM module exports the related APIs on an already-defined object combined with the Node.js module caching, run the following code snippet once and use the exported object throughout your project:

For ECMAScript modules (ESM):

import { RudderAnalytics } from '@rudderstack/analytics-js';

const rudderAnalytics = new RudderAnalytics();
rudderAnalytics.load(<write-key>, <data-plane-url>', {});

window.rudderanalytics = rudderAnalytics;

For CJS using the require method:

var RudderAnalytics = require("@rudderstack/analytics-js");

const rudderAnalytics = new RudderAnalytics();
rudderAnalytics.load(WRITE_KEY, DATA_PLANE_URL);

window.rudderanalytics = rudderAnalytics;

exports.rudderanalytics = rudderAnalytics;

Load options

The SDK v3 introduces the following new load options in addition to the existing load options:

ParameterTypeDescription
pluginsSDKBaseURLStringBase URL path used by SDK to load the plugins.

Default value: https://cdn.rudderlabs.com/beta/3.0.0-beta/<buildType>/plugins
destinationsQueueOptionsObjectSee destinationsQueueOptions for more information.
pluginsString arrayList of plugins you want the SDK to load.

See Plugins for more information.

Default value: Array of all the plugins names.
polyfillURLStringURL to load polyfills, not necessarily from polyfill.io.

Default value: https://polyfill.io/v3/polyfill.min.js with dynamic calculation of missing features from the browser.

Example: Suppose your browser is missing the following features required by the SDK:
  • Array.includes
  • String.startsWith
  • Promise
Then the polyfill URL will look like this:
https://polyfill.io/v3/polyfill.min.js?features=Array.prototype.includes%2CString.prototype.startsWith%2CPromise.
storageObjectConfigures different storage-related features like, encryption, migration, etc.

See Storage for more information.

destinationsQueueOptions

The destinationsQueueOptions object controls the behavior of the in-memory queue that buffers events before sending them to a device mode destination. Its structure is defined as follows:

rudderanalytics.load("<write-key>", "<data-plane-url>", {
  destinationsQueueOptions: {
    maxItems: 100
  }
});
ParameterTypeDescription
maxItemsIntegerMaximum number of events the device mode destinations (in-memory) queue can store while the destinations are still loading.

Default value: 100

Plugins

Plugins are JavaScript SDK v3 features that you can optionally load on demand.

NameDescription
BeaconQueueUses the browser’s Beacon utility to send a batch of events to the data plane instead of a single event per request.

See Sending events using Beacon for more information.
ErrorReportingReports SDK errors to RudderStack.
ExternalAnonymousIdLets you migrate the external anonymous user IDs to RudderStack’s anonymousId.

See anonymousIdOptions for more information.
GoogleLinkerProvides anonymousId from Google AMP Linker URL query parameters.
NativeDestinationQueueStores incoming events in a queue and sends them to the device mode destinations.
StorageEncryptionLegacyExisting (SDK version <= v1.1) approach to encrypt/decrypt data before storing it in cookies/local storage.
StorageEncryptionLightweight alternative to encrypt/decrypt data before storing it in cookies/local storage.
StorageMigratorAssists the SDK in migrating the legacy encrypted persisted data.
XhrQueueStores incoming events in a local storage retry queue and sends them to the data plane via XMLHttpRequest.
OneTrustConsentManagerIntegrates the OneTrust consent manager.

See OneTrust consent management for web for more information.
KetchConsentManagerIntegrates the Ketch consent manager.

See Ketch consent management for web for more information.
BugsnagIntegrates Bugsnag as an error reporting provider.

If you wish to use only a subset of the SDK features, you can explicitly specify the plugins in the plugins option while loading the SDK.

For example, if you do not want the external anonymous ID, Google Linker and error reporting features, you can provide an array of plugin names excluding those plugins. A sample snippet highlighting how to set the plugins load option in this scenario:

plugins:["BeaconQueue", "DeviceModeDestinations", "NativeDestinationQueue",
"StorageEncryptionLegacy", "StorageEncryption", "StorageMigrator",
"XhrQueue", "OneTrustConsentManager", "KetchConsentManager"]
warning
If you set the plugins option and exclude certain plugins from the list (for example, OneTrustConsentManager), setting the associated load options while loading the SDK (for example, cookieConsentManager to OneTrust) will have no effect.

If you do not specify the plugins option while loading the JavaScript SDK v3, then RudderStack considers all plugins mentioned in the above table by default.

info

Once the list of plugins is determined, the SDK automatically loads a subset of them based on your load options, browser capabilities, and source configuration.

For example, if you set cookieConsentManager to Ketch, then the SDK will not load OneTrustConsentManager plugin by default.

Lazyloading plugins

For older browsers and users intentionally using the legacy Javascript SDK, RudderStack bundles the plugins with the core SDK. However, for modern browsers, the SDK lazy loads the plugins as multiple small chunks. These chunks are very small in size and loaded with the website parallelly.

The SDK’s bundling tool uses a package that supports Module Federation to bundle each feature into separate code chunks that can have interdependency among themselves. These chunks act as containers and can expose and consume code between them, creating a single, unified application. These chunks or plugins are then uploaded into CDN.

Depending on the load options, browser capabilities, and source configuration, RudderStack fetches these plugins from the remote location at runtime when the SDK starts to load.

Storage

You can use the storage load option to configure different storage-specific features like encryption and migration.

rudderanalytics.load("<write-key>", "<data-plane-url>", {
  storage: {
    encryption: {
      version: "v3" / "legacy"
    },
    migrate: true / false
  }
});
ParameterTypeDescription
encryptionObjectConfigures the encryption type for persisted user data. It consists of a version parameter that accepts two values - v3 and legacy.

The SDK uses Base64 encryption if you set version to v3 and AES encryption for legacy.

Default value: v3
migrateBooleanMigrates persisted legacy encrypted data if set to true.

Default value: false
warning

If you set version to legacy, then you must also load the StorageEncryptionLegacy plugin. For v3, you must load the StorageEncryption plugin.

Similarly, if you set migrate to true, then you must also load the StorageMigrator plugin.

Note that:

  • If you access the SDK persisted data directly from the cookie or local storage, you must update the custom decryption logic.
  • All sites under the same top-level domain must use the same encryption version. For example, if xyz.test.com uses the JavaScript SDK v3 and abc.test.com uses a legacy SDK version (v1.1), then you should set the storage load option as follows:
rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
  storage: {
    encryption: {
      version: "legacy"
    }
  },
  // other load options
});
  • Migrating all your subdomain sites to use SDK v3 is recommended.

Cookieless tracking

While loading the JavaScript SDK v3, you can specify the information to store (userId, anonymousId, session information, etc.) and whether to store it in your browser’s cookies, local storage, in-memory storage, or not store it at all.

See Cookieless Tracking guide for more information.

New features

Event dispatching for SDK initialized and ready phases

The SDK v3 supports dispatching two new events to document - RSA_Initialised and RSA_Ready - when it is in the initialized and ready phases respectively.

These events provide a reference to the analytics instance (analyticsInstance) whenever you want to use it to invoke any API method, for example, getUserId.

You can listen to the above events as follows:

<script>
   document.addEventListener('RSA_Initialised', function(e) {
     console.log('RSA_Initialised', e.detail.analyticsInstance);
   })
   
   document.addEventListener('RSA_Ready', function(e) {
     console.log('RSA_Ready', e.detail.analyticsInstance);
   })
   
</script>

You can use this feature as an alternative to the ready API method and the onLoaded load option for orchestration with JavaScript frameworks and libraries. It is useful in cases where relevant business logic is in functions that cannot be declared alongside the analytics integration or they need to declared on a decoupled codebase for some reason.

Batching in XHRQueue plugin

The JavaScript SDK v3 provides the XhrQueue plugin that leverages queueOptions to control the behavior of the persistence queue that buffers events in local storage before sending them to the data plane.

You can also send a batch of events to the data plane using the queueOptions.batch object while loading the SDK:

rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
  queueOptions: {
    minRetryDelay: 1000, // ms
    batch: {
      enabled: true,
      maxItems: 100,
      maxSize: 1024 * 512 // 512 KB
      flushInterval: 60000 // ms
    },
    ...
  },
  ...
});

The following table details the queueOptions.batch object parameters:

ParameterData typeDescriptionDefault value
enabledBooleanDetermines if the SDK should activate the batching functionality.false
maxItemsIntegerMaximum number of events in a batch.100
maxSizeIntegerMaximum batch payload size.512 KB (Also, the maximum configurable value)
flushIntervalIntegerMinimum interval between two batch requests.60000 ms
info

Note that:

  • queueOptions.batch is an optional object, meaning batching is disabled by default.
  • The SDK makes a batch request when either of the following criteria is met:
    • maxItems in a batch is reached.
    • maxSize of the batch is reached.
    • Time period of flushInterval ms has elapsed since the last batch request.

Debugging

The SDK v3 exposes the following objects globally that can assist in debugging:

NameDescription
window.rudderAnalyticsBuildTypeDenotes the build type to load based on browser capabilities (modern or legacy).
window.RudderStackGlobalsContains some SDK application-level values, preloadBuffer (before it is consumed) and the SDK instance state per write key. You can use it to debug and see values in state at any point in time.

Breaking changes

Source configuration URL

The default source configuration host has changed from rudderlabs.com to rudderstack.com. If you were previously forwarding the source configuration host, you must proxy https://api.rudderstack.com instead of https://api.rudderlabs.com.

See How to use custom domains for more information.

Installation and loading

  • The SDK loading snippet has changed.

  • The file name is changed from rudder-analytics.min.js to rsa.min.js.

  • The NPM package is changed from rudder-sdk-js to @rudderstack/analytics-js.

  • In previous versions, RudderStack provided a list of methods in the loading snippet that can be buffered before loading the SDK. These methods are:

    • load, page, track, identify, alias, group, ready, reset.
    • Other methods are getAnonymousId, setAnonymousId, getUserId, getUserTraits, getGroupId, getGroupTraits, startSession, endSession, and getSessionId.
    • With this update, all the GET methods are removed from the preload supported list of methods.
  • GET type methods like getAnonymousId, getGroupTraits, etc. will work correctly only once the SDK is loaded successfully. This is because the data is available in the storage and requires successful loading of the plugins.

Client-side events filtering

For client-side events filtering:

  • Empty and non-string event names are not allowlisted anymore.
  • Event name comparison is case-sensitive.

Adblocking

Adblocker detection logic is updated. The SDK does not use the Google AdSense script anymore.

Storage and encryption

Other changes



Questions? Contact us by email or on Slack