Skip to main content
Ask your AI

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_INITIALIZED and 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​

PropertyTypeDescriptionMore
categoryMapRecord<string, string>Map the CMP's consent categories (keys) to walkerOS consent groups (values).
explicitOnlybooleanOnly 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'.
v3EventNamestringWindow 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.

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": true,
      "history": [
        {
          "type": "explicit",
          "status": true
        }
      ]
    }
  }
]
Mapping
{
  "settings": {
    "categoryMap": {
      "essential": "functional",
      "functional": "analytics"
    }
  }
}
Out
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.

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": true,
      "history": [
        {
          "type": "explicit",
          "status": true
        }
      ]
    }
  }
]
Out
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.

Event
[
  {
    "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
        }
      ]
    }
  }
]
Out
// no output

Full consent

Usercentrics reports every category accepted via an explicit decision; the source emits a walker consent command granting essential, functional, and marketing.

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": true,
      "history": [
        {
          "type": "explicit",
          "status": true
        }
      ]
    }
  }
]
Out
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.

Event
[
  {
    "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
        }
      ]
    }
  }
]
Out
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.

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
        }
      ]
    }
  }
]
Out
elb("walker consent", {
  "essential": true,
  "functional": true,
  "marketing": false
})

How it works​

The source uses Usercentrics' official integration surface across both API versions:

  1. Already initialized: if the CMP loaded before the source, consent is read statically through the official getters (V2 UC_UI.getServicesBaseInfo(), V3 __ucCmp.getConsentDetails()).

  2. CMP loads after the source: the source listens for UC_UI_INITIALIZED and reads the current consent state once the CMP is ready.

  3. User decisions: the source listens for UC_UI_CMP_EVENT (consent actions ACCEPT_ALL, DENY_ALL, and SAVE) and republishes the updated state.

  4. Category mapping: maps categories via categoryMap and calls elb('walker consent', state) with the mapped consent state.

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.

Reference​

💡 Need implementation support?
elbwalker offers hands-on support: setup review, measurement planning, destination mapping, and live troubleshooting. Book a 2-hour session (€399)