c15t
Version:
Headless JavaScript consent management platform for cookie banners, privacy preferences, consent storage, and script gating.
226 lines (181 loc) • 8.03 kB
Markdown
title: Consent Manager Provider
description: Reference page for consent manager provider.
group: reference
`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.
## Options Reference
|Property|Value|
|:--|:--|
|Type Name|\`CommonInlineStoreOptions\`|
|Source Path|\`./packages/ui/src/theme/options.ts\`|
\*ExtractedTypeTable: Could not extract "CommonInlineStoreOptions" from "./packages/ui/src/theme/options.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
|Property|Value|
|:--|:--|
|Type Name|\`ConsentManagerContentOptions\`|
|Source Path|\`./packages/ui/src/theme/options.ts\`|
\*ExtractedTypeTable: Could not extract "ConsentManagerContentOptions" from "./packages/ui/src/theme/options.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
|Property|Value|
|:--|:--|
|Type Name|\`UIOptions\`|
|Source Path|\`./packages/ui/src/theme/types.ts\`|
\*ExtractedTypeTable: Could not extract "UIOptions" from "./packages/ui/src/theme/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
## Content Security Policy
c15t injects a `<style id="c15t-theme">` element for your theme tokens, and the script loader injects a `<script>` element per consented vendor. Under a nonce-based Content Security Policy, both are blocked unless they carry your nonce.
Pass it once through the `nonce` option and c15t applies it to everything it injects:
```tsx
<ConsentManagerProvider
options={{
mode: 'offline',
nonce: yourRequestNonce,
}}
>
{children}
</ConsentManagerProvider>
```
A `nonce` set on an individual script definition still wins, so you can override a single vendor without changing the provider.
> 📝 **Note:**
> Browsers hide the nonce content attribute once a policy is active. Inspecting the element shows no nonce="", but element.nonce still returns the value — this is expected and not a sign that c15t dropped it.
### Inline style attributes
The `nonce` option covers the elements c15t injects. It cannot cover inline `style="..."` attributes, which several components rely on — a nonce never authorizes a style attribute, because nonces apply to elements only.
Style attributes are governed by `style-src-attr`, and when that directive is absent CSP falls back to `style-src`. A nonce-based style policy therefore blocks them:
```http
style-src 'self' 'nonce-abc123';
```
To keep the nonce requirement for stylesheets while still allowing style attributes, set `style-src-attr` explicitly:
```http
style-src 'self' 'nonce-abc123';
style-src-attr 'unsafe-inline';
```
> ⚠️ **Warning:**
> 'unsafe-inline' on style-src-attr permits any inline style attribute on the page. That is weaker than a nonce, but far narrower than replacing your nonce-based style-src with 'unsafe-inline', which would additionally authorize arbitrary injected \<style> elements. Note that adding 'unsafe-inline' alongside a nonce achieves nothing — a directive that specifies a nonce ignores it. If your threat model does not allow this, expect components that use inline styles to render unstyled.
## 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
|Property|Value|
|:--|:--|
|Type Name|\`ConsentManagerProviderProps\`|
|Source Path|\`./packages/react/src/types/consent-manager.ts\`|
\*ExtractedTypeTable: Could not extract "ConsentManagerProviderProps" from "./packages/react/src/types/consent-manager.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*