Usercentrics
Integrates Usercentrics consent management with walkerOS using the official Usercentrics events and consent getters, mapping category consent state to walkerOS consent groups.
We recommend the source package below over a hand-written event listener: it handles version detection, returning-visitor restore, and explicit-consent gating for you.
Installation
npm install @walkeros/web-source-cmp-usercentrics
import { startFlow } from '@walkeros/collector';
import { sourceUsercentrics } from '@walkeros/web-source-cmp-usercentrics';
await startFlow({
sources: {
consent: {
code: sourceUsercentrics,
config: {
settings: {
categoryMap: {
essential: 'functional',
functional: 'functional',
marketing: 'marketing',
},
},
},
},
},
});
V2 vs V3 support
The source supports both Usercentrics V2 (window.UC_UI) and V3
(window.__ucCmp) APIs. With the default apiVersion: 'auto', detection runs
at init:
- If the CMP is already initialized, consent is read statically through the
official getters (V2
UC_UI.getServicesBaseInfo(), V3__ucCmp.getConsentDetails()). - If no CMP is present yet, the source listens for
UC_UI_INITIALIZEDand reads the current state once the CMP signals it is ready, so late-loading CMPs are still caught. - When both APIs are available, V3 is preferred.
Set apiVersion: 'v2' or 'v3' to force a specific integration.
v3EventName replaces UC_UI_CMP_EVENT for the V3 adapter; it does not add a
second event. The source processes only events on that name whose
detail.type is ACCEPT_ALL, DENY_ALL or SAVE, so leave it at its
default.
Custom mapping example
await startFlow({
sources: {
consent: {
code: sourceUsercentrics,
config: {
settings: {
categoryMap: {
essential: 'functional',
functional: 'functional',
marketing: 'marketing',
},
explicitOnly: true,
},
},
},
},
});
Categories missing from categoryMap are reported under their Usercentrics
slug (the default map is empty). A category is true only when the user
accepted all of it: V3 state ALL_ACCEPTED, or in V2 every service in that
category. When several categories map to the same group, the group is true
only if all of them are, so with the map above functional requires both
essential and functional.
Configuration
This source uses the standard source config wrapper (consent, data, env, id, ...). For the shared fields see source configuration. Package-specific fields live under config.settings and are listed below.
Settings
| Property | Type | Description | More |
|---|---|---|---|
categoryMap | Record<string, string> | Map the CMP's consent categories (keys) to walkerOS consent groups (values). | |
explicitOnly | boolean | Only publish when the user has actively decided (V3: consent.type EXPLICIT; V2: an EXPLICIT entry in service consent history). Implicit/default page-load states are suppressed. Set false to publish any snapshot including implicit. Default: true. | |
apiVersion | 'auto' | 'v2' | 'v3' | Which Usercentrics API to use. 'auto' uses V3 (window.__ucCmp) when present, else V2 (window.UC_UI), and listens for both while neither is loaded. Default: 'auto'. | |
v3EventName | string | Window event the V3 adapter listens to for consent decisions, replacing UC_UI_CMP_EVENT. Only events whose detail.type is ACCEPT_ALL, DENY_ALL or SAVE are processed. Default: 'UC_UI_CMP_EVENT'. |
Mapping
This package does not define custom rule-level settings. For the standard rule fields (consent, condition, data, batch, name, policy) see mapping.
Examples
Category map override
A custom categoryMap remaps essential to functional and functional to analytics before emitting the walker consent command.
[
{
"categorySlug": "essential",
"consent": {
"status": true,
"history": [
{
"type": "explicit",
"status": true
}
]
}
},
{
"categorySlug": "functional",
"consent": {
"status": true,
"history": [
{
"type": "explicit",
"status": true
}
]
}
},
{
"categorySlug": "marketing",
"consent": {
"status": true,
"history": [
{
"type": "explicit",
"status": true
}
]
}
}
]{
"settings": {
"categoryMap": {
"essential": "functional",
"functional": "analytics"
}
}
}elb("walker consent", {
"functional": true,
"analytics": true,
"marketing": true
})Consent change via CMP event
An ACCEPT_ALL decision fires UC_UI_CMP_EVENT; the source re-reads the services and emits the updated consent.
[
{
"categorySlug": "essential",
"consent": {
"status": true,
"history": [
{
"type": "explicit",
"status": true
}
]
}
},
{
"categorySlug": "functional",
"consent": {
"status": true,
"history": [
{
"type": "explicit",
"status": true
}
]
}
},
{
"categorySlug": "marketing",
"consent": {
"status": true,
"history": [
{
"type": "explicit",
"status": true
}
]
}
}
]elb("walker consent", {
"essential": true,
"functional": true,
"marketing": true
})First visit implicit (suppressed)
A first-visit snapshot carrying only implicit history is suppressed by the default explicitOnly gate, so no consent command is emitted.
[
{
"categorySlug": "essential",
"consent": {
"status": true,
"history": [
{
"type": "implicit",
"status": true
}
]
}
},
{
"categorySlug": "functional",
"consent": {
"status": false,
"history": [
{
"type": "implicit",
"status": false
}
]
}
},
{
"categorySlug": "marketing",
"consent": {
"status": false,
"history": [
{
"type": "implicit",
"status": false
}
]
}
}
]// no outputFull consent
Usercentrics reports every category accepted via an explicit decision; the source emits a walker consent command granting essential, functional, and marketing.
[
{
"categorySlug": "essential",
"consent": {
"status": true,
"history": [
{
"type": "explicit",
"status": true
}
]
}
},
{
"categorySlug": "functional",
"consent": {
"status": true,
"history": [
{
"type": "explicit",
"status": true
}
]
}
},
{
"categorySlug": "marketing",
"consent": {
"status": true,
"history": [
{
"type": "explicit",
"status": true
}
]
}
}
]elb("walker consent", {
"essential": true,
"functional": true,
"marketing": true
})Minimal consent
A "Deny all" explicit decision leaves only essential granted; functional and marketing are emitted as false.
[
{
"categorySlug": "essential",
"consent": {
"status": true,
"history": [
{
"type": "explicit",
"status": true
}
]
}
},
{
"categorySlug": "functional",
"consent": {
"status": false,
"history": [
{
"type": "explicit",
"status": false
}
]
}
},
{
"categorySlug": "marketing",
"consent": {
"status": false,
"history": [
{
"type": "explicit",
"status": false
}
]
}
}
]elb("walker consent", {
"essential": true,
"functional": false,
"marketing": false
})Returning visitor static read
When the CMP is already initialized with a stored explicit decision, the static read at init re-publishes that choice without any further event.
[
{
"categorySlug": "essential",
"consent": {
"status": true,
"history": [
{
"type": "explicit",
"status": true
}
]
}
},
{
"categorySlug": "functional",
"consent": {
"status": true,
"history": [
{
"type": "explicit",
"status": true
}
]
}
},
{
"categorySlug": "marketing",
"consent": {
"status": false,
"history": [
{
"type": "explicit",
"status": false
}
]
}
}
]elb("walker consent", {
"essential": true,
"functional": true,
"marketing": false
})How it works
The source uses Usercentrics' official integration surface across both API versions:
-
Already initialized: if the CMP loaded before the source, consent is read statically through the official getters (V2
UC_UI.getServicesBaseInfo(), V3__ucCmp.getConsentDetails()). -
CMP loads after the source: the source listens for
UC_UI_INITIALIZEDand reads the current consent state once the CMP is ready. -
User decisions: the source listens for
UC_UI_CMP_EVENT(consent actionsACCEPT_ALL,DENY_ALL, andSAVE) and republishes the updated state. -
Category mapping: maps categories via
categoryMapand callselb('walker consent', state)with the mapped consent state.
Explicit consent
By default (explicitOnly: true), the source publishes only states the user has
actively decided. It reads this from the official consent metadata: V3
consent.type === EXPLICIT, and V2 an EXPLICIT entry in the service consent
history. First-visit defaults stay suppressed. Set explicitOnly: false to also
publish implicit/default consent.
Timing considerations
A returning visitor's prior choice is applied on page load, either from the
static getter read (CMP already initialized) or on UC_UI_INITIALIZED (CMP loads
later). First-visit defaults stay suppressed under the default
explicitOnly: true. Set explicitOnly: false to publish any snapshot,
including implicit defaults.