Consent Management in JavaScript SDK
11 minute read
This guide explains the consent management functionality and the various consent tracking approaches supported by the JavaScript SDK.
Overview
The JavaScript SDK supports RudderStack’s consent management functionality and lets you manage data sent to downstream destinations based on user consent. This feature is crucial for respecting user privacy preferences and complying with data protection regulations.
With this functionality, you can:
- Seamlessly integrate with popular consent management providers like OneTrust, Ketch, and iubenda. You can also set up a custom consent management provider.
- Configure consent settings for multiple providers for your web source.
- Unlock advanced use cases like pre-consent user tracking where you can track user activity and control the SDK’s behavior before and after the user provides their consent.
See Consent filtering requirements for more information on the consent filtering settings at destination and event payload levels.
Consent management approaches
There are two primary approaches to implementing consent management with the RudderStack JavaScript SDK:
Post-consent user tracking
Post-consent user tracking is the most common implementation where you load the JavaScript SDK only after the user has provided consent. This approach is straightforward but has limitations:
- It ensures that no tracking occurs before consent is given
- You cannot control SDK behavior before consent is provided
- It may result in loss of some initial user activity data
See the OneTrust post-consent user tracking setup for a sample implementation.
Pre-consent user tracking
Pre-consent user tracking allows you to track some user activity and control SDK behavior both before and after the user provides consent. This approach offers more flexibility because of the following reasons:
- It minimizes data loss related to attribution, acquisition, and the overall user journey
- You can choose to track users as fully anonymous, or persist only the information you need, for example, their sessions or the
anonymousIdidentifier - It allows for a more nuanced approach to data collection based on consent status
- There is no particular restriction on the loading order of the SDKs
See the OneTrust pre-consent user tracking setup for a sample implementation.
The presence of consent management object in the event’s context (
context.consentManagement) helps you differentiate between the pre- and post-consent events.RudderStack does not add any other extra property to differentiate these events.
Key components of pre-consent user tracking
This section explains the key components of pre-consent user tracking in the JavaScript SDK.
The preConsent object
You can use the preConsent object while loading the JavaScript SDK to enable pre-consent mode and define the SDK’s events delivery behavior. Use the storage load option to define what the SDK persists before the user provides consent.
- Pass the consent management platform’s information in the
consentManagementobject as aloadAPI option. - Add the
storageandpreConsentobjects, as shown:
rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
consentManagement: {
enabled: true,
provider: "oneTrust" / "ketch" / "iubenda" / "custom"
},
storage: { // Optional; defines what the SDK persists
entries: {
anonymousId: {
type: "cookieStorage"
}
}
},
preConsent: {
enabled: true, // false by default
storage: { // Optional
enabled: true, // false by default; applies the storage option before consent
},
events: { // Optional
delivery: "immediate" / "buffer", // Default is "immediate"
},
},
...
// Other load options
});If you setpreConsent.enabledtotrue, the JavaScript SDK does not load the device mode integrations.
Storage in pre-consent mode
Set preConsent.storage.enabled to true to apply the storage load option during the pre-consent phase. The same option then decides what the SDK persists both before and after the user provides consent, and only the fallback differs: while pre-consent mode is active, the SDK persists an entry only if you explicitly set a storage type for it, either through storage.entries.<entry>.type or the global storage.type. The SDK does not persist any entry you leave unconfigured.
Once you invoke the consent API, the SDK reverts to its usual default (cookieStorage) for the entries you have not configured.
preConsent.storage.enabledisfalseby default, so your existing configuration is unaffected until you set it. Without it, the deprecatedpreConsent.storage.strategycontinues to decide what the SDK persists, and if you set neither, the SDK persists nothing before consent.If you set both,
preConsent.storage.enabledtakes precedence and the SDK ignoresstrategy.
You can set a storage type for the following entries: userId, userTraits, anonymousId, groupId, groupTraits, initialReferrer, initialReferringDomain, sessionInfo, and authToken.
Each entry accepts cookieStorage, localStorage, sessionStorage, memoryStorage, or none. See Configure Persistent Data Storage in JavaScript SDK for what each value means.
The following example persists both the anonymous ID and the session information before consent, and buffers the events until the user consents:
rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
consentManagement: {
enabled: true,
provider: "oneTrust"
},
storage: {
entries: {
anonymousId: {
type: "cookieStorage"
},
sessionInfo: {
type: "cookieStorage"
}
}
},
preConsent: {
enabled: true,
storage: {
enabled: true
},
events: {
delivery: "buffer"
}
}
// Other load options
});Because each entry is configured on its own, you can mix and match them, for example, persist the anonymous ID in a cookie, keep the session information in memory, and store nothing else.
Cookie storage strategy
preConsent.storage.strategyis deprecated and will be removed in the next major version. Use thestorageload option instead.The option still works exactly as before, but the SDK logs a deprecation warning when you set it. While it is in effect, the SDK does not persist the entries that the strategy excludes, even if you configure a storage type for them.
If you set both
strategyandpreConsent.storage.enabled, the latter takes precedence and the SDK ignoresstrategy.
The SDK stores information in the pre-consent mode based on the following cookie storage strategies:
| Value | Description |
|---|---|
none | Fully anonymous tracking where RudderStack does not store any cookies. For this value, note that:
|
session | Fully anonymous tracking where RudderStack stores only the session tracking cookie (manual or automatic), if it is active. For this value, note that:
|
anonymousId | RudderStack persists only the anonymous ID (anonymousId).For this value, note that:
|
Migrate from the cookie storage strategy
Replace strategy with enabled: true in the preConsent.storage object, then move the configuration to the storage load option:
| Deprecated strategy | Equivalent configuration |
|---|---|
strategy: "none" | Omit preConsent.storage entirely. This is the default behavior. |
strategy: "session" | Set preConsent.storage.enabled to true and set storage: { entries: { sessionInfo: { type: "cookieStorage" } } } |
strategy: "anonymousId" | Set preConsent.storage.enabled to true and set storage: { entries: { anonymousId: { type: "cookieStorage" } } } |
SetpreConsent.storage.enabledtotruewhen you removestrategy. If you removestrategywithout it, the SDK persists nothing before consent.
For example, the following configuration persists only the session information before consent:
// Before
rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
consentManagement: {
enabled: true,
provider: "oneTrust"
},
preConsent: {
enabled: true,
storage: {
strategy: "session"
}
}
// Other load options
});// After
rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
consentManagement: {
enabled: true,
provider: "oneTrust"
},
storage: {
entries: {
sessionInfo: {
type: "cookieStorage"
}
}
},
preConsent: {
enabled: true,
storage: {
enabled: true
}
}
// Other load options
});The storage option is not limited to the three strategies. You can persist any combination of entries and pick a different storage type for each one.
Session tracking in pre-consent mode
To retain session tracking during the pre-consent phase, set a storage type for the sessionInfo entry. Unless you also persist anonymousId, the SDK generates a new anonymousId per event until consent is granted.
If you do not persist sessionInfo but still want to group pre-consent events into a session, use the setCustomContext API. Custom context is in-memory only and does not write any cookies or storage, so it is compatible with all pre-consent storage configurations.
Since custom context is in-memory only, the identifier resets on page reload and groups events within a single page load.
For example, generate a session-like identifier and attach it to all events:
// Before consent: attach a custom session identifier
rudderanalytics.setCustomContext({
preConsentSessionId: crypto.randomUUID()
});After the user grants consent and native session tracking resumes, clear the custom context:
// After consent is granted
rudderanalytics.clearCustomContext();Events delivery strategy
As the SDK does not load any device mode destinations in pre-consent mode, you can control the events delivery strategy for the cloud mode destinations only.
The SDK delivers events in the pre-consent mode based on the following values:
| Value | Description |
|---|---|
immediate | RudderStack sends the events to the RudderStack backend (data plane) immediately as they occur. |
buffer | The SDK buffers the events in the local storage. You can use the consent API to decide what to do with these buffered events.This option works with any pre-consent storage configuration. |
The SDK decides the delivery for preload events (events instrumented to the SDK before it is loaded), ad-blocked page view events, and Query string API events, based on the above options (immediate/buffer) set in the pre-consent mode.
The consent API
You can invoke the JavaScript SDK’s consent API once the user consent is available. The SDK then comes out of the pre-consent mode and resumes normal functioning.
A sample implementation for a custom provider is shown below:
<script type = "text/javascript">
// consent provider callback
function ConsentManagerWrapper() { /// Pseudo name
if (window.isConsented()) { // Pseudo name
// Pass the allowed and denied category IDs for custom setup
rudderanalytics.consent({
options: {
trackConsent: true / false, // Optional; default is false
consentManagement: {
allowedConsentIds: ['<category_id_1>','<category_id_2>',.....], // Required for Custom provider
deniedConsentIds: ['<category_id_3>','<category_id_4>',.....]
}, // Required for Custom provider
storage: {
type: "cookieStorage", // Other supported values are "localStorage","sessionStorage", "memoryStorage", and "none"
entries: {
userId: {
type: "localStorage" // Other supported values are "cookieStorage","sessionStorage", "memoryStorage", and "none"
},
userTraits: {
type: "cookieStorage" // Other supported values are "localStorage","sessionStorage", "memoryStorage", and "none"
},
sessionInfo: {
type: "cookieStorage" // Other supported values are "localStorage","sessionStorage", "memoryStorage", and "none"
}
}
}, // Optional
integrations: IntegrationOpts, // Optional
discardPreConsentEvents: true / false, // Optional; default is false
sendPageEvent: true / false // Optional, default is false
}
});
}
}
</script>The consent API options are listed below:
| Parameter | Type | Description |
|---|---|---|
trackConsent | Boolean | Determines if the SDK should send a track event with the name Consent Management Interaction.Default value: false |
consentManagement | Object | Lets you pass the user consent data in case of a custom consent management provider. The SDK requires the allowedConsentIds and deniedConsentIds fields in case of a Custom consent provider. |
storage | Object | Lets you configure the different storage-specific options like:
|
integrations | Object | Instructs the SDK to filter the integrations before the consent filtering takes effect. |
discardPreConsentEvents | Boolean | Determines if the SDK should discard all the pre-consent events buffered previously. Default value: false |
sendPageEvent | Boolean | Determines if the SDK should send a page event.Default value: false |
The SDK does the following once you invoke the consent API:
- Loads the device mode integrations based on consent.
- Fetches the consent information from the consent manager.
- Stores persistent user information like
userId,anonymousId,traits, etc. according to the specifiedstorageoption. - Discards or replays the buffered pre-consent events to the destinations based on the
discardPreconsentEventsparameter.
The SDK also sends any events received after the user gives consent to the destinations immediately.
Set different pre-consent and post-consent storage options
You can configure different storage options for pre-consent and post-consent user tracking that let you:
- Ensure data is stored appropriately based on the consent status and reduce unnecessary data collection.
- Maintain seamless user experience while respecting users’ privacy preferences.
Follow these steps to set different storage options for pre-consent and post-consent user tracking:
- Configure the storage options while loading the JavaScript SDK. These options define what the SDK persists before consent.
- Set
preConsent.enabledandpreConsent.storage.enabledtotrue. You can also define the SDK’s events delivery strategy here.
rudderanalytics.load(WRITE_KEY, DATA_PLANE_URL, {
storage: {
encryption: {
version: "v3" / "legacy"
},
entries: {
sessionInfo: {
type: "cookieStorage" // Other available options are "localStorage", "sessionStorage", "memoryStorage", and "none".
}
}
// Other storage options
},
consentManagement: {
enabled: true,
provider: "oneTrust" / "ketch" / "iubenda" / "custom" // Specify your consent management provider
},
preConsent: {
enabled: true,
storage: { // Optional; applies the storage option before consent
enabled: true // Optional; false by default
},
events: { // Optional; defines SDK's events delivery behavior
delivery: "buffer" // Optional; other accepted value is "immediate"
},
},
// Other load options
});In the above snippet, the SDK persists only the session information before consent, as sessionInfo is the only entry with a storage type.
- Invoke the
consentAPI after the user provides consent. You can also define the SDK’s post-consent storage options here.
rudderanalytics.consent({
trackConsent: true,
discardPreConsentEvents: true, // Optional; default value is false
storage: {
type: "localStorage" // Other available options are "cookieStorage", "sessionStorage", "memoryStorage", and "none".
}
});The storage options you pass to theconsentAPI persist across its invocations. If you invoke the API again without any storage options, the SDK retains the storage configuration from the previous invocation.
Integration with consent management platforms
RudderStack’s JavaScript SDK integrates with various consent management platforms:
These integrations enable:
- Flexibility to use the consent management tool that best fits your needs
- Seamless coordination between consent decisions and data collection
- Compliance with privacy regulations across different jurisdictions