---
title: ConsentManagerProvider
description: The root provider component that initializes the consent system and makes consent state available to all child components.
---
`ConsentManagerProvider` is the root component for the c15t consent system. It initializes the consent store, detects the user's jurisdiction, resolves translations, and provides consent state to all child components via React context.

Every other c15t component and hook must be rendered inside this provider.

## Basic Usage

```tsx
import { type ReactNode } from 'react';
import { ConsentManagerProvider, ConsentBanner, ConsentDialog } from '@c15t/react';

export default function ConsentManager({ children }: { children: ReactNode }) {
  return (
    <ConsentManagerProvider
      options={{
        mode: 'hosted',
        backendURL: 'https://your-instance.c15t.dev',
        consentCategories: ['necessary', 'measurement', 'marketing'],
      }}
    >
      <ConsentBanner />
      <ConsentDialog />
      {children}
    </ConsentManagerProvider>
  );
}
```

## Options Reference

### CommonInlineStoreOptions

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|enabled|boolean \|undefined|Whether c15t should be active.|true|Optional|
|callbacks|[Callbacks \|undefined](https://c15t.com/docs/frameworks/react/callbacks)|Event callbacks for consent actions.|-|Optional|
|scripts|[Script \|undefined](https://c15t.com/docs/frameworks/react/script-loader)|Dynamically load scripts based on consent state.|-|Optional|
|legalLinks|Object \|undefined|Configuration for the legal links.|-|Optional|
|storageConfig|StorageConfig \|undefined|Storage configuration for consent persistence.|-|Optional|
|user|User \|undefined|The user's information. Usually your own internal ID for the user from your auth provider.|-|Optional|
|overrides|Overrides \|undefined|Forcefully set values like country, region, language for the consent manager. These values will override the values detected from the browser.|-|Optional|
|networkBlocker|[NetworkBlockerConfig \|undefined](https://c15t.com/docs/frameworks/react/network-blocker)|Configuration for the network request blocker.|-|Optional|
|iab|[IABConfig \|undefined](https://c15t.com/docs/frameworks/react/iab/overview)|IAB TCF 2.3 configuration.|-|Optional|
|ssrData|[Object \|undefined](https://c15t.com/docs/frameworks/react/server-side)|SSR-prefetched data for hydration.|-|Optional|

#### `callbacks` Callbacks

Event callbacks for consent actions.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|onBannerFetched|Callback\<OnBannerFetchedPayload> \|undefined|Called when the consent banner is fetched.|-|Optional|
|onConsentSet|Callback\<OnConsentSetPayload> \|undefined|Called when the consent is set.|-|Optional|
|onConsentChanged|Callback\<OnConsentChangedPayload> \|undefined|Called only when an explicit consent save changes the previously saved consent state.|-|Optional|
|onError|Callback\<OnErrorPayload> \|undefined|Called when an error occurs.|-|Optional|
|onBeforeConsentRevocationReload|Callback\<OnConsentSetPayload> \|undefined|Called before the page reloads when consent is revoked.|-|Optional|

#### `scripts` Script

Dynamically load scripts based on consent state.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|id|string|Unique identifier for the script|-|✅ Required|
|src|string \|undefined|URL of the script to load|-|Optional|
|textContent|string \|undefined|Inline JavaScript code to execute|-|Optional|
|category|HasCondition\<AllConsentNames>|Consent category or condition required to load this script|-|✅ Required|
|callbackOnly|boolean \|undefined|Whether this is a callback-only script that doesn't need to load an external resource. When true, no script tag will be added to the DOM, only callbacks will be executed.|-|Optional|
|persistAfterConsentRevoked|boolean \|undefined|Whether the script should persist after consent is revoked.|-|Optional|
|alwaysLoad|boolean \|undefined|Whether the script should always load regardless of consent state. This is useful for scripts like Google Tag Manager or PostHog that manage their own consent state internally. The script will load immediately and never be unloaded based on consent changes. Note: When using this option, you are responsible for ensuring the script itself respects user consent preferences through its own consent management.|-|Optional|
|fetchPriority|"high" \|"low" \|"auto" \|undefined|Priority hint for browser resource loading|-|Optional|
|attributes|Record\<string, string> \|undefined|Additional attributes to add to the script element|-|Optional|
|async|boolean \|undefined|Whether to use async loading|-|Optional|
|defer|boolean \|undefined|Whether to defer script loading|-|Optional|
|nonce|string \|undefined|Content Security Policy nonce|-|Optional|
|anonymizeId|boolean \|undefined|Whether to use an anonymized ID for the script element, this helps ensure the script is not blocked by ad blockers|-|Optional|
|target|"head" \|"body" \|undefined|Where to inject the script element in the DOM. Options: \`'head'\`: Scripts are appended to \`\<head>\` (default); \`'body'\`: Scripts are appended to \`\<body>\`|-|Optional|
|onBeforeLoad|((info: ScriptCallbackInfo) => void) \|undefined|Callback executed before the script is loaded|-|Optional|
|onLoad|((info: ScriptCallbackInfo) => void) \|undefined|Callback executed when the script loads successfully|-|Optional|
|onError|((info: ScriptCallbackInfo) => void) \|undefined|Callback executed if the script fails to load|-|Optional|
|onConsentChange|((info: ScriptCallbackInfo) => void) \|undefined|Callback executed whenever the consent store is changed. This callback only applies to scripts already loaded.|-|Optional|
|vendorId|string \|number \|undefined|IAB TCF vendor ID - links script to a registered vendor. When in IAB mode, the script will only load if this vendor has consent. Takes precedence over \`category\` when in IAB mode. Use custom vendor IDs (string or number) to gate non-IAB vendors too.|-|Optional|
|iabPurposes|number\[] \|undefined|IAB TCF purpose IDs this script requires consent for. When in IAB mode and no vendorId is set, the script will only load if ALL specified purposes have consent.|-|Optional|
|iabLegIntPurposes|number\[] \|undefined|IAB TCF legitimate interest purpose IDs. These purposes can operate under legitimate interest instead of consent. The script loads if all iabPurposes have consent OR all iabLegIntPurposes have legitimate interest established.|-|Optional|
|iabSpecialFeatures|number\[] \|undefined|IAB TCF special feature IDs this script requires. Options: 1: Use precise geolocation data; 2: Actively scan device characteristics for identification|-|Optional|

#### `legalLinks`

Configuration for the legal links.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|privacyPolicy|LegalLink \|undefined|-|-|✅ Required|
|cookiePolicy|LegalLink \|undefined|-|-|✅ Required|
|termsOfService|LegalLink \|undefined|-|-|✅ Required|

#### `storageConfig` StorageConfig

Storage configuration for consent persistence.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|storageKey|string \|undefined|Custom storage key for localStorage and cookies|-|Optional|
|crossSubdomain|boolean \|undefined|Enable cross-subdomain cookies by default|-|Optional|
|defaultDomain|string \|undefined|Custom default domain for cookies|-|Optional|
|defaultExpiryDays|number \|undefined|Default cookie expiration in days|-|Optional|

#### `user` User

The user's information. Usually your own internal ID for the user from your auth provider.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|id|string|Usually your own internal ID for the user from your auth provider|-|✅ Required|
|identityProvider|string \|undefined|The identity provider of the user. Usually the name of the identity provider e.g. 'clerk', 'auth0', 'custom', etc.|-|Optional|

#### `overrides` Overrides

Forcefully set values like country, region, language for the consent manager. These values will override the values detected from the browser.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|country|string \|undefined|Country code to forcefully set|-|Optional|
|region|string \|undefined|Region code to forcefully set|-|Optional|
|language|string \|undefined|Language code to forcefully set|-|Optional|
|gpc|boolean \|undefined|Override the Global Privacy Control (GPC) signal. When \`true\`, simulates GPC being active (opt-out of marketing/measurement). When \`false\`, suppresses the real browser GPC signal. When \`undefined\`, falls back to the browser's \`navigator.globalPrivacyControl\`.|-|Optional|

#### `networkBlocker` NetworkBlockerConfig

Configuration for the network request blocker.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|enabled|boolean \|undefined|Whether the network blocker is enabled.|-|Optional|
|initialConsents|ConsentState \|undefined|The consent state snapshot that is currently used for blocking logic.|-|Optional|
|logBlockedRequests|boolean \|undefined|Whether to automatically log blocked requests to the console.|-|Optional|
|onRequestBlocked|((info: BlockedRequestInfo) => void) \|undefined|Callback invoked whenever a request is blocked.|-|Optional|
|rules|NetworkBlockerRule|Domain rules that determine which requests should be blocked.|-|✅ Required|

#### `iab` IABConfig

IAB TCF 2.3 configuration.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|enabled|boolean|Enable IAB TCF 2.3 mode. Note: Only works in 'hosted' client mode (legacy alias: 'c15t') because it requires a backend. Options: Fetch GVL from gvl.consent.io; Initialize \_\_tcfapi CMP API; Generate TC Strings for IAB compliance|-|✅ Required|
|\_module|IABModule \|undefined|IAB runtime module injected by \`@c15t/iab\`.|-|Optional|
|cmpId|number \|undefined|CMP ID registered with IAB Europe. When using consent.io as the backend, this is automatically provided via the \`/init\` endpoint — no client-side configuration needed. Only set this if you self-host and have your own CMP registration. A valid (non-zero) CMP ID is required for IAB TCF compliance.|-|Optional|
|cmpVersion|string \|number \|undefined|CMP version. When omitted, defaults to package version from \`\~/cmp-defaults\` (which uses \~/version).|-|Optional|
|vendors|number\[] \|undefined|IAB-registered vendor IDs to include (optional). Used to scope the vendor list when fetching GVL or when hosted fallback paths are used (e.g. if GVL fetch fails).|-|Optional|
|customVendors|NonIABVendor \|undefined|Custom vendors not registered with IAB. These are displayed separately in the consent UI with a note that they have different privacy practices than IAB vendors.|-|Optional|
|publisherCountryCode|string \|undefined|Publisher country code (2-letter ISO).|-|Optional|
|isServiceSpecific|boolean \|undefined|Whether consent is service-specific (not global).|-|Optional|
|gvl|Object \|undefined \|null|Pre-loaded Global Vendor List for testing or SSR. Options: Testing (avoids network calls and mocking complexity); SSR (use server-fetched GVL); Offline/air-gapped deployments|-|Optional|

#### `ssrData`

SSR-prefetched data for hydration.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|init|Object \|undefined \|null|Init endpoint response with jurisdiction, location, translations, and optional GVL.|-|✅ Required|
|gvl|Object \|undefined \|null|Global Vendor List data for IAB TCF mode. Note: When init returns 200 without gvl, client IAB settings are overridden to disabled.|-|Optional|
|metadata|SSRInitRequestMetadata \|undefined|Optional metadata for debugging SSR transport behavior.|-|Optional|

### ConsentManagerContentOptions

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|i18n|I18nConfig \|undefined|Preferred i18n configuration in c15t v2.|-|Optional|
|translations|[TranslationConfig \|undefined](https://c15t.com/docs/frameworks/react/internationalization)|Translation configuration to seed the store with.|-|Optional|
|consentCategories|[AllConsentNames \|undefined](https://c15t.com/docs/frameworks/react/concepts/consent-categories)|Consent categories to show in the consent banner.|-|Optional|

#### `i18n` I18nConfig

Preferred i18n configuration in c15t v2.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|messages|Record\<string, Partial\<Translations>> \|undefined|Translation message map keyed by language code (\`en\`, \`de\`, \`fr\`, ...).|-|✅ Required|
|locale|string \|undefined|Preferred language code used as the initial fallback locale.|-|Optional|
|detectBrowserLanguage|boolean \|undefined|Whether to auto-detect from browser language settings.|-|Optional|

#### `translations` TranslationConfig

Translation configuration to seed the store with.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|translations|Record\<string, Partial\<Translations>> \|undefined|-|-|✅ Required|
|defaultLanguage|string \|undefined|-|-|Optional|
|disableAutoLanguageSwitch|boolean \|undefined|-|-|Optional|

### UIOptions

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|theme|[Theme \|undefined](https://c15t.com/docs/frameworks/react/styling/tokens)|Visual theme to apply.|-|Optional|
|disableAnimation|boolean \|undefined|Whether to disable animations.|false|Optional|
|scrollLock|boolean \|undefined|Whether to lock scroll when dialogs are open.|false|Optional|
|trapFocus|boolean \|undefined|Whether to trap focus within dialogs.|true|Optional|
|colorScheme|["light" \|"dark" \|"system" \|undefined](https://c15t.com/docs/frameworks/react/styling/color-scheme)|Color scheme preference. With this option, you can force the theme to be light, dark or system. Otherwise, the theme will be detected if you have '.dark' classname in your document.|-|Optional|
|noStyle|[boolean \|undefined](https://c15t.com/docs/frameworks/react/headless)|Whether to disable default styles.|false|Optional|

#### `theme` Theme

Visual theme to apply.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|colors|ColorTokens \|undefined|Color palette for light mode.|-|Optional|
|dark|ColorTokens \|undefined|Dark mode color overrides.|-|Optional|
|typography|TypographyTokens \|undefined|Typography settings for text elements.|-|Optional|
|spacing|SpacingTokens \|undefined|Spacing scale for internal padding and margins.|-|Optional|
|radius|RadiusTokens \|undefined|Border radius scale for rounded corners.|-|Optional|
|shadows|ShadowTokens \|undefined|Box shadow scale for depth and elevation.|-|Optional|
|motion|MotionTokens \|undefined|Animation and transition timing.|-|Optional|
|consentActions|Object \|undefined|Semantic button styling for consent actions.|-|Optional|
|slots|ComponentSlots \|undefined|Component-specific style overrides.|-|Optional|

## Mode: hosted vs offline

```tsx
// Hosted mode — persists to hosted backend
<ConsentManagerProvider
  options={{
    mode: 'hosted',
    backendURL: 'https://your-instance.c15t.dev',
  }}
>

// Offline mode — local cookie storage only
<ConsentManagerProvider
  options={{
    mode: 'offline',
  }}
>
```

See [Client Modes](/docs/frameworks/react/concepts/client-modes) for a detailed comparison.

## Legal Links

`legalLinks` defines the URLs shown in consent UI text (banner, dialog, and widget where applicable).
Configure only the links you want to expose.

```tsx
<ConsentManagerProvider
  options={{
    backendURL: 'https://your-instance.c15t.dev',
    legalLinks: {
      privacyPolicy: {
        href: '/privacy',
        target: '_self',
      },
      cookiePolicy: {
        href: '/cookies',
        target: '_self',
      },
      termsOfService: {
        href: 'https://example.com/terms',
        target: '_blank',
        rel: 'noopener noreferrer',
        label: 'Terms of Service',
      },
    },
  }}
>
```

Notes:

* Omitting a key (for example `termsOfService`) hides that link.
* `label` overrides the translated text for that single link.
* Use `_self` for internal pages and `_blank` + `rel="noopener noreferrer"` for external pages.
* Control which of the configured links render in each component via the component's `legalLinks` prop.

## Overrides

`overrides` lets you force location/language signals instead of browser or network detection.
This is useful for QA, local development, and preview environments.

```tsx
<ConsentManagerProvider
  options={{
    backendURL: 'https://your-instance.c15t.dev',
    overrides: {
      country: 'DE',
      region: 'BY',
      language: 'de-DE',
    },
  }}
>
```

You can also override Global Privacy Control (GPC) behavior during testing:

```tsx
<ConsentManagerProvider
  options={{
    backendURL: 'https://your-instance.c15t.dev',
    overrides: {
      gpc: true,
    },
  }}
>
```

> ⚠️ **Warning:**
> Treat overrides as an environment/testing tool. Avoid hard-coding production overrides unless that behavior is intentional for your deployment.

## Policy Packs

In hosted mode (recommended), the backend resolves the correct policy automatically — no frontend policy config needed:

```tsx
<ConsentManagerProvider
  options={{
    backendURL: 'https://your-instance.c15t.dev',
  }}
>
```

### Fallback: Offline Policies

When no backend is available, `ConsentManagerProvider` accepts `offlinePolicy.policyPacks` for local policy resolution during development, testing, previews, or temporary backend outages:

```tsx
<ConsentManagerProvider
  options={{
    mode: 'offline',
    offlinePolicy: {
      i18n: {
        defaultProfile: 'default',
        messages: {
          default: {
            translations: {
              en: { cookieBanner: { title: 'Privacy choices' } },
            },
          },
          qc: {
            fallbackLanguage: 'fr',
            translations: {
              en: { cookieBanner: { title: 'Quebec Privacy Settings' } },
              fr: { cookieBanner: { title: 'Paramètres de confidentialité du Québec' } },
            },
          },
        },
      },
      policyPacks: [
        {
          id: 'qc_opt_in',
          match: { regions: [{ country: 'CA', region: 'QC' }] },
          i18n: { messageProfile: 'qc' },
          consent: { model: 'opt-in', expiryDays: 365 },
          ui: { mode: 'banner' },
        },
        {
          id: 'default_world',
          match: { isDefault: true },
          consent: { model: 'none' },
          ui: { mode: 'none' },
        },
      ],
    },
    overrides: {
      country: 'CA',
      region: 'QC',
    },
  }}
>
```

Notes:

* `offlinePolicy` is only used in `offline` mode.
* Treat offline policies as a development/testing tool or resilience fallback, not the primary production source of truth.
* `offlinePolicy.i18n` lets offline mode mirror hosted `messageProfile` and profile-local `fallbackLanguage` behavior.
* Omitting `offlinePolicy.policyPacks` uses the built-in synthetic opt-in fallback banner. Hosted network fallback uses the same opt-in banner.
* `offlinePolicy: { policyPacks: [] }` is explicit no-banner mode.
* In hosted mode, backend `policyPacks` remain the source of truth — frontend offline policies never override a live backend decision.

Read the full guide at [Policy Packs](/docs/frameworks/react/policy-packs) and the conceptual model at [Policy Packs Concept](/docs/frameworks/react/concepts/policy-packs).

## Props

### ConsentManagerProviderProps

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|children|ReactNode|React children to render within the provider.|-|✅ Required|
|options|[ConsentManagerOptions](https://c15t.com/docs/frameworks/react/components/consent-manager-provider)|Configuration options for the consent manager. This includes core, React, store, and translation settings.|-|✅ Required|

#### `options` ConsentManagerOptions

Configuration options for the consent manager. This includes core, React, store, and translation settings.

|Property|Type|Description|Default|Required|
|:--|:--|:--|:--|:--:|
|store|StoreOptions \|undefined|-|-|Optional|
|offlinePolicy|OfflinePolicyConfig \|undefined|Top-level offline policy configuration.|-|Optional|
|storageConfig|StorageConfig \|undefined|Storage configuration for consent persistence|-|Optional|
|mode|"custom" \|"hosted" \|"c15t" \|"offline" \|undefined|Operating mode - custom endpoint implementation|-|Optional|
|backendURL|string \|undefined|Backend URL is not used in custom mode|-|Optional|
|enabled|boolean \|undefined|Whether c15t should be active.|-|Optional|
|callbacks|Callbacks \|undefined|Event callbacks for consent actions.|-|Optional|
|scripts|Script \|undefined|Dynamically load scripts based on consent state.|-|Optional|
|legalLinks|Partial\<Record\<keyof LegalLinksTranslations, LegalLink>> \|undefined|Configuration for the legal links.|-|Optional|
|user|User \|undefined|The user's information. Usually your own internal ID for the user from your auth provider.|-|Optional|
|overrides|Overrides \|undefined|Forcefully set values like country, region, language for the consent manager. These values will override the values detected from the browser.|-|Optional|
|networkBlocker|NetworkBlockerConfig \|undefined|Configuration for the network request blocker.|-|Optional|
|iab|IABConfig \|undefined|IAB TCF 2.3 configuration.|-|Optional|
|ssrData|Promise\<SSRInitialData \|undefined> \|undefined|SSR-prefetched data for hydration.|-|Optional|
|theme|Theme \|undefined|Visual theme to apply.|-|Optional|
|disableAnimation|boolean \|undefined|Whether to disable animations.|-|Optional|
|scrollLock|boolean \|undefined|Whether to lock scroll when dialogs are open.|-|Optional|
|trapFocus|boolean \|undefined|Whether to trap focus within dialogs.|-|Optional|
|colorScheme|"light" \|"dark" \|"system" \|undefined|Color scheme preference. With this option, you can force the theme to be light, dark or system. Otherwise, the theme will be detected if you have '.dark' classname in your document.|-|Optional|
|noStyle|boolean \|undefined|Whether to disable default styles.|-|Optional|
|i18n|I18nConfig \|undefined|Preferred i18n configuration in c15t v2.|-|Optional|
|translations|TranslationConfig \|undefined|Translation configuration to seed the store with.|-|Optional|
|consentCategories|AllConsentNames \|undefined|Consent categories to show in the consent banner.|-|Optional|
