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.


Install SDK
You can install the JavaScript SDK v3 via a CDN or using NPM.
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);
})();
Installation workflow
The installation code snippets listed above perform the following actions:
- Based on browser capabilities, load either the
legacy
or modern
bundle. - Load Polyfill for
Promise
, if required, as it is necessary for the SDK to start up. - Create an array to store the events until the
rudderanalytics
object is ready. - Store the following methods to replay them when the
rudderanalytics
object is ready:
- Load the
rudderanalytics
object with the specified write key. - 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

- 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:
Parameter | Type | Description |
---|
pluginsSDKBaseURL | String | Base URL path used by SDK to load the plugins.
Default value: https://cdn.rudderlabs.com/beta/3.0.0-beta/<buildType>/plugins |
destinationsQueueOptions | Object | See destinationsQueueOptions for more information. |
plugins | String array | List of plugins you want the SDK to load.
See Plugins for more information.
Default value: Array of all the plugins names. |
polyfillURL | String | URL 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 . |
storage | Object | Configures 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
}
});
Parameter | Type | Description |
---|
maxItems | Integer | Maximum 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.
Name | Description |
---|
BeaconQueue | Uses 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. |
ErrorReporting | Reports SDK errors to RudderStack. |
ExternalAnonymousId | Lets you migrate the external anonymous user IDs to RudderStack’s anonymousId .
See anonymousIdOptions for more information. |
GoogleLinker | Provides anonymousId from Google AMP Linker URL query parameters. |
NativeDestinationQueue | Stores incoming events in a queue and sends them to the device mode destinations. |
StorageEncryptionLegacy | Existing (SDK version <= v1.1) approach to encrypt/decrypt data before storing it in cookies/local storage. |
StorageEncryption | Lightweight alternative to encrypt/decrypt data before storing it in cookies/local storage. |
StorageMigrator | Assists the SDK in migrating the legacy encrypted persisted data. |
XhrQueue | Stores incoming events in a local storage retry queue and sends them to the data plane via XMLHttpRequest. |
OneTrustConsentManager | Integrates the OneTrust consent manager.
See OneTrust consent management for web for more information. |
KetchConsentManager | Integrates the Ketch consent manager.
See Ketch consent management for web for more information. |
Bugsnag | Integrates 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"]

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.

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
}
});
Parameter | Type | Description |
---|
encryption | Object | Configures 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 |
migrate | Boolean | Migrates persisted legacy encrypted data if set to true .
Default value: false |

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:
Parameter | Data type | Description | Default value |
---|
enabled | Boolean | Determines if the SDK should activate the batching functionality. | false |
maxItems | Integer | Maximum number of events in a batch. | 100 |
maxSize | Integer | Maximum batch payload size. | 512 KB (Also, the maximum configurable value) |
flushInterval | Integer | Minimum interval between two batch requests. | 60000 ms |

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:
Name | Description |
---|
window.rudderAnalyticsBuildType | Denotes the build type to load based on browser capabilities (modern or legacy). |
window.RudderStackGlobals | Contains 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