> Part of the walkerOS documentation. Project overview and full index: <https://www.walkeros.io/llms.txt>

# Usercentrics

Integrates [Usercentrics](https://usercentrics.com/) consent management with walkerOS using the official Usercentrics events and consent getters, mapping category or service 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[​](#installation "Direct link to 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',

          },

        },

      },

    },

  },

});
```

## Configuration[​](#configuration "Direct link to Configuration")

This <!-- -->source<!-- --> uses the standard <!-- -->source<!-- --> config wrapper (consent, data, env, id, ...). For the shared fields see [source<!-- --> configuration](https://www.walkeros.io/docs/sources.md#configuration). Package-specific fields live under `config.settings` and are listed below.

## Settings[​](#settings "Direct link to 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. |      |

## Mapping[​](#mapping "Direct link to Mapping")

This package does not define custom rule-level settings. For the standard rule fields (consent, condition, data, batch, name, policy) see [mapping](https://www.walkeros.io/docs/mapping.md).

## 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
})
```

| Setting        | Type                     | Default             | Description                                                |
| -------------- | ------------------------ | ------------------- | ---------------------------------------------------------- |
| `apiVersion`   | `'auto' \| 'v2' \| 'v3'` | `'auto'`            | Which Usercentrics API to target (auto-detects by default) |
| `categoryMap`  | `Record<string, string>` | `{}`                | Maps Usercentrics categories to walkerOS consent groups    |
| `explicitOnly` | `boolean`                | `true`              | Only publish when the user has actively decided            |
| `v3EventName`  | `string`                 | `'UC_UI_CMP_EVENT'` | V3 event name, override only for a custom admin event      |

There is no configurable data-layer event setting: the source listens to the always-emitted official Usercentrics events, so no `eventName` configuration or Usercentrics admin window-event setup is required.

### V2 vs V3 support[​](#v2-vs-v3-support "Direct link to 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.

### Custom mapping example[​](#custom-mapping-example "Direct link to Custom mapping example")

```
await startFlow({

  sources: {

    consent: {

      code: sourceUsercentrics,

      config: {

        settings: {

          categoryMap: {

            essential: 'functional',

            functional: 'functional',

            marketing: 'marketing',

          },

          explicitOnly: true,

        },

      },

    },

  },

});
```

## How it works[​](#how-it-works "Direct link to 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.

### Explicit consent[​](#explicit-consent "Direct link to 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[​](#timing-considerations "Direct link to 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. Ensure the consent source has no `require` constraints so it initializes immediately.

## Reference[​](#reference "Direct link to Reference")

* [Usercentrics developer documentation](https://usercentrics.com/docs/)
* [Source code](https://github.com/elbwalker/walkerOS/tree/main/packages/web/sources/cmps/usercentrics)
