@c15t/nextjs 2.2.1 → 3.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +103 -142
- package/README.md +4 -4
- package/dist/api.js +1 -0
- package/dist/config.js +1 -0
- package/dist/devtools.js +2 -0
- package/dist/headers.js +1 -0
- package/dist/iab/styles.css +1 -1
- package/dist/iab/styles.tw3.css +27 -19
- package/dist/index.js +1 -1
- package/dist/middleware.js +1 -0
- package/dist/node-bridge.js +1 -0
- package/dist/pages.js +1 -0
- package/dist/proxy.js +1 -0
- package/dist/root.js +2 -0
- package/dist/server.js +1 -0
- package/dist/static.js +1 -0
- package/dist/styles.css +1 -1
- package/dist/styles.tw3.css +67 -29
- package/dist/version.js +1 -1
- package/dist-types/api.d.ts +88 -0
- package/dist-types/config.d.ts +110 -0
- package/dist-types/devtools.d.ts +1 -0
- package/dist-types/headers.d.ts +4 -0
- package/dist-types/index.d.ts +28 -10
- package/dist-types/middleware.d.ts +15 -0
- package/dist-types/node-bridge.d.ts +57 -0
- package/dist-types/pages.d.ts +88 -0
- package/dist-types/proxy.d.ts +34 -0
- package/dist-types/root.d.ts +92 -0
- package/dist-types/server.d.ts +164 -0
- package/dist-types/static.d.ts +42 -0
- package/dist-types/types.d.ts +5 -36
- package/dist-types/version.d.ts +1 -1
- package/docs/README.md +103 -142
- package/docs/assets/v3/brand-bar.png +0 -0
- package/docs/assets/v3/brand-card.png +0 -0
- package/docs/assets/v3/choice-wall.png +0 -0
- package/docs/assets/v3/mobile-card.png +0 -0
- package/docs/assets/v3/preferences.png +0 -0
- package/docs/customization/overview.md +45 -0
- package/docs/customization/recipes.md +79 -0
- package/docs/customization/slots.md +55 -0
- package/docs/customization/tokens.md +76 -0
- package/docs/customization/translations.md +49 -0
- package/docs/frameworks/next/api-reference/data-fetching.md +416 -0
- package/docs/frameworks/next/app-router.md +403 -0
- package/docs/frameworks/next/client-side.md +118 -0
- package/docs/frameworks/next/components/consent-banner.md +251 -211
- package/docs/frameworks/next/components/consent-dialog-link.md +96 -35
- package/docs/frameworks/next/components/consent-dialog-trigger.md +74 -149
- package/docs/frameworks/next/components/consent-dialog.md +189 -134
- package/docs/frameworks/next/components/consent-manager-provider.md +68 -318
- package/docs/frameworks/next/components/consent-widget.md +172 -114
- package/docs/frameworks/next/components/dev-tools.md +199 -40
- package/docs/frameworks/next/components/frame.md +137 -42
- package/docs/frameworks/next/concepts/consent-categories.md +24 -89
- package/docs/frameworks/next/concepts/policy-presets.md +142 -0
- package/docs/frameworks/next/content-security-policy.md +189 -0
- package/docs/frameworks/next/data-fetching.md +74 -0
- package/docs/frameworks/next/geography-headers.md +251 -0
- package/docs/frameworks/next/headless.md +95 -185
- package/docs/frameworks/next/hooks/use-consent-manager/overview.md +42 -163
- package/docs/frameworks/next/iab/overview.md +37 -107
- package/docs/frameworks/next/optimization.md +158 -194
- package/docs/frameworks/next/pages-router.md +296 -0
- package/docs/frameworks/next/quickstart.md +31 -132
- package/docs/frameworks/next/script-loader.md +140 -465
- package/docs/frameworks/next/server-side.md +97 -130
- package/docs/frameworks/next/static-export.md +164 -0
- package/docs/frameworks/next/styling/overview.md +174 -248
- package/docs/frameworks/next/troubleshooting.md +134 -144
- package/docs/guides/consent-state.md +60 -0
- package/docs/guides/data-fetching.md +163 -0
- package/docs/guides/deployment-modes.md +63 -0
- package/docs/guides/troubleshooting.md +68 -0
- package/docs/guides/verify-consent.md +62 -0
- package/docs/integrations/adobe-analytics.md +239 -105
- package/docs/integrations/ahrefs-analytics.md +238 -104
- package/docs/integrations/amplitude.md +219 -157
- package/docs/integrations/building-integrations.md +32 -224
- package/docs/integrations/clear-on-revocation.md +167 -0
- package/docs/integrations/clearbit.md +247 -86
- package/docs/integrations/cloudflare-web-analytics.md +250 -84
- package/docs/integrations/crisp.md +251 -97
- package/docs/integrations/databuddy.md +259 -153
- package/docs/integrations/fathom-analytics.md +239 -96
- package/docs/integrations/google-maps.md +328 -207
- package/docs/integrations/google-tag-manager.md +248 -96
- package/docs/integrations/google-tag.md +261 -90
- package/docs/integrations/heap.md +222 -149
- package/docs/integrations/hightouch.md +225 -131
- package/docs/integrations/hotjar.md +239 -90
- package/docs/integrations/intercom.md +239 -98
- package/docs/integrations/linkedin-insights.md +243 -113
- package/docs/integrations/logrocket.md +241 -123
- package/docs/integrations/matomo-analytics.md +256 -111
- package/docs/integrations/meta-pixel.md +197 -324
- package/docs/integrations/microsoft-clarity.md +233 -114
- package/docs/integrations/microsoft-uet.md +245 -110
- package/docs/integrations/mixpanel-analytics.md +252 -87
- package/docs/integrations/openai-pixel.md +441 -0
- package/docs/integrations/overview.md +95 -133
- package/docs/integrations/pirsch.md +249 -96
- package/docs/integrations/plausible-analytics.md +241 -100
- package/docs/integrations/posthog.md +353 -214
- package/docs/integrations/promptwatch.md +251 -81
- package/docs/integrations/reddit-pixel.md +226 -173
- package/docs/integrations/rudderstack.md +244 -187
- package/docs/integrations/rybbit-analytics.md +244 -91
- package/docs/integrations/segment.md +238 -92
- package/docs/integrations/snapchat-pixel.md +240 -110
- package/docs/integrations/tiktok-pixel.md +249 -81
- package/docs/integrations/umami-analytics.md +242 -95
- package/docs/integrations/vercel-analytics.md +242 -90
- package/docs/integrations/x-pixel.md +238 -104
- package/docs/integrations/youtube.md +354 -142
- package/docs/upgrade-v3.md +334 -0
- package/iab/styles.css +1 -1
- package/iab/styles.tw3.css +1 -1
- package/package.json +106 -65
- package/readme.json +3 -3
- package/src/iab/styles.css +1 -1
- package/src/iab/styles.tw3.css +1 -1
- package/src/styles.css +1 -1
- package/src/styles.tw3.css +1 -1
- package/styles.css +1 -1
- package/styles.tw3.css +1 -1
- package/client/components/consent-dialog-link.js +0 -3
- package/client/components/integrations.js +0 -3
- package/dist/components/integrations/index.cjs +0 -1
- package/dist/components/integrations/index.js +0 -1
- package/dist/headless.cjs +0 -1
- package/dist/index.cjs +0 -1
- package/dist/libs/browser-initial-data.cjs +0 -1
- package/dist/libs/browser-initial-data.js +0 -1
- package/dist/libs/initial-data.cjs +0 -1
- package/dist/libs/initial-data.js +0 -1
- package/dist/types.cjs +0 -1
- package/dist/version.cjs +0 -1
- package/dist-types/components/integrations/index.d.ts +0 -1
- package/dist-types/libs/browser-initial-data.d.ts +0 -9
- package/dist-types/libs/initial-data.d.ts +0 -33
- package/docs/frameworks/next/building-headless-components.md +0 -379
- package/docs/frameworks/next/callbacks.md +0 -186
- package/docs/frameworks/next/concepts/client-modes.md +0 -177
- package/docs/frameworks/next/concepts/consent-models.md +0 -117
- package/docs/frameworks/next/concepts/cookie-management.md +0 -122
- package/docs/frameworks/next/concepts/glossary.md +0 -24
- package/docs/frameworks/next/concepts/initialization-flow.md +0 -149
- package/docs/frameworks/next/concepts/policy-packs.md +0 -230
- package/docs/frameworks/next/hooks/use-color-scheme.md +0 -41
- package/docs/frameworks/next/hooks/use-consent-manager/checking-consent.md +0 -96
- package/docs/frameworks/next/hooks/use-consent-manager/location-info.md +0 -97
- package/docs/frameworks/next/hooks/use-consent-manager/setting-consent.md +0 -94
- package/docs/frameworks/next/hooks/use-draggable.md +0 -59
- package/docs/frameworks/next/hooks/use-focus-trap.md +0 -42
- package/docs/frameworks/next/hooks/use-reduced-motion.md +0 -37
- package/docs/frameworks/next/hooks/use-ssr-status.md +0 -32
- package/docs/frameworks/next/hooks/use-text-direction.md +0 -50
- package/docs/frameworks/next/hooks/use-translations.md +0 -55
- package/docs/frameworks/next/iab/consent-banner.md +0 -91
- package/docs/frameworks/next/iab/consent-dialog.md +0 -129
- package/docs/frameworks/next/iab/use-gvl-data.md +0 -21
- package/docs/frameworks/next/iframe-blocking.md +0 -106
- package/docs/frameworks/next/internationalization.md +0 -207
- package/docs/frameworks/next/network-blocker.md +0 -140
- package/docs/frameworks/next/policy-packs.md +0 -248
- package/docs/frameworks/next/styling/classnames.md +0 -94
- package/docs/frameworks/next/styling/color-scheme.md +0 -84
- package/docs/frameworks/next/styling/css-variables.md +0 -53
- package/docs/frameworks/next/styling/slots.md +0 -94
- package/docs/frameworks/next/styling/tailwind.md +0 -137
- package/docs/frameworks/next/styling/tokens.md +0 -156
- package/docs/shared/concepts/client-modes.md +0 -103
- package/docs/shared/concepts/consent-categories.md +0 -41
- package/docs/shared/concepts/consent-models.md +0 -72
- package/docs/shared/concepts/cookie-management.md +0 -88
- package/docs/shared/concepts/glossary.md +0 -24
- package/docs/shared/concepts/initialization-flow.md +0 -105
- package/docs/shared/concepts/policy-packs.md +0 -225
- package/docs/shared/react/components/consent-banner.md +0 -242
- package/docs/shared/react/components/consent-dialog-link.md +0 -45
- package/docs/shared/react/components/consent-dialog-trigger.md +0 -185
- package/docs/shared/react/components/consent-dialog.md +0 -119
- package/docs/shared/react/components/consent-manager-provider.md +0 -225
- package/docs/shared/react/components/consent-widget.md +0 -121
- package/docs/shared/react/components/dev-tools.md +0 -81
- package/docs/shared/react/components/frame.md +0 -52
- package/docs/shared/react/guides/building-headless-components.md +0 -110
- package/docs/shared/react/guides/callbacks.md +0 -89
- package/docs/shared/react/guides/headless.md +0 -31
- package/docs/shared/react/guides/iframe-blocking.md +0 -65
- package/docs/shared/react/guides/internationalization.md +0 -123
- package/docs/shared/react/guides/network-blocker.md +0 -72
- package/docs/shared/react/guides/optimization.md +0 -44
- package/docs/shared/react/guides/policy-packs.md +0 -173
- package/docs/shared/react/guides/script-loader.md +0 -311
- package/docs/shared/react/hooks/use-color-scheme.md +0 -31
- package/docs/shared/react/hooks/use-consent-manager/checking-consent.md +0 -95
- package/docs/shared/react/hooks/use-consent-manager/location-info.md +0 -96
- package/docs/shared/react/hooks/use-consent-manager/overview.md +0 -74
- package/docs/shared/react/hooks/use-consent-manager/setting-consent.md +0 -93
- package/docs/shared/react/hooks/use-draggable.md +0 -30
- package/docs/shared/react/hooks/use-focus-trap.md +0 -20
- package/docs/shared/react/hooks/use-reduced-motion.md +0 -33
- package/docs/shared/react/hooks/use-ssr-status.md +0 -16
- package/docs/shared/react/hooks/use-text-direction.md +0 -38
- package/docs/shared/react/hooks/use-translations.md +0 -15
- package/docs/shared/react/iab/consent-banner.md +0 -60
- package/docs/shared/react/iab/consent-dialog.md +0 -76
- package/docs/shared/react/iab/overview.md +0 -80
- package/docs/shared/react/iab/use-gvl-data.md +0 -21
- package/docs/shared/react/styling/classnames.md +0 -93
- package/docs/shared/react/styling/color-scheme.md +0 -35
- package/docs/shared/react/styling/css-variables.md +0 -53
- package/docs/shared/react/styling/overview.md +0 -261
- package/docs/shared/react/styling/slots.md +0 -93
- package/docs/shared/react/styling/stylesheet-entrypoint.md +0 -8
- package/docs/shared/react/styling/tailwind.md +0 -88
- package/docs/shared/react/styling/tokens.md +0 -155
- package/docs/shared/troubleshooting.md +0 -82
|
@@ -1,327 +1,77 @@
|
|
|
1
1
|
---
|
|
2
|
-
title:
|
|
3
|
-
description:
|
|
4
|
-
|
|
2
|
+
title: ConsentRoot
|
|
3
|
+
description: Pass server-resolved consent state and shared configuration to the
|
|
4
|
+
Next.js ConsentRoot.
|
|
5
5
|
group: frameworks
|
|
6
6
|
---
|
|
7
|
-
`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.
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
## Mount one root
|
|
10
9
|
|
|
11
|
-
|
|
10
|
+
`ConsentRoot` wraps the React `ConsentProvider` and connects it to your
|
|
11
|
+
Next.js configuration and server-resolved state. Mount it once; it already
|
|
12
|
+
supplies the provider used by consent components and hooks.
|
|
12
13
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
export default function ConsentManager({ children }: { children: ReactNode }) {
|
|
18
|
-
return (
|
|
19
|
-
<ConsentManagerProvider
|
|
20
|
-
options={{
|
|
21
|
-
mode: 'hosted',
|
|
22
|
-
backendURL: '/api/c15t',
|
|
23
|
-
consentCategories: ['necessary', 'measurement', 'marketing'],
|
|
24
|
-
}}
|
|
25
|
-
>
|
|
26
|
-
<ConsentBanner />
|
|
27
|
-
<ConsentDialog />
|
|
28
|
-
{children}
|
|
29
|
-
</ConsentManagerProvider>
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
## Options Reference
|
|
35
|
-
|
|
36
|
-
|Property|Value|
|
|
37
|
-
|:--|:--|
|
|
38
|
-
|Type Name|\`CommonInlineStoreOptions\`|
|
|
39
|
-
|Source Path|\`./packages/ui/src/theme/options.ts\`|
|
|
40
|
-
|
|
41
|
-
\*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.\*
|
|
42
|
-
|
|
43
|
-
|Property|Value|
|
|
44
|
-
|:--|:--|
|
|
45
|
-
|Type Name|\`ConsentManagerContentOptions\`|
|
|
46
|
-
|Source Path|\`./packages/ui/src/theme/options.ts\`|
|
|
47
|
-
|
|
48
|
-
\*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.\*
|
|
49
|
-
|
|
50
|
-
|Property|Value|
|
|
51
|
-
|:--|:--|
|
|
52
|
-
|Type Name|\`UIOptions\`|
|
|
53
|
-
|Source Path|\`./packages/ui/src/theme/types.ts\`|
|
|
54
|
-
|
|
55
|
-
\*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.\*
|
|
56
|
-
|
|
57
|
-
## Mode: hosted vs offline
|
|
58
|
-
|
|
59
|
-
```tsx
|
|
60
|
-
// Hosted mode — persists to hosted backend
|
|
61
|
-
<ConsentManagerProvider
|
|
62
|
-
options={{
|
|
63
|
-
mode: 'hosted',
|
|
64
|
-
backendURL: '/api/c15t',
|
|
65
|
-
}}
|
|
66
|
-
>
|
|
67
|
-
|
|
68
|
-
// Offline mode — local cookie storage only
|
|
69
|
-
<ConsentManagerProvider
|
|
70
|
-
options={{
|
|
71
|
-
mode: 'offline',
|
|
72
|
-
}}
|
|
73
|
-
>
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
See [Client Modes](/docs/frameworks/next/concepts/client-modes) for a detailed comparison.
|
|
77
|
-
|
|
78
|
-
## Content Security Policy
|
|
79
|
-
|
|
80
|
-
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.
|
|
81
|
-
|
|
82
|
-
Pass it once through the `nonce` option and c15t applies it to everything it injects:
|
|
83
|
-
|
|
84
|
-
```tsx
|
|
85
|
-
<ConsentManagerProvider
|
|
86
|
-
options={{
|
|
87
|
-
mode: 'offline',
|
|
88
|
-
nonce: yourRequestNonce,
|
|
89
|
-
}}
|
|
90
|
-
>
|
|
91
|
-
{children}
|
|
92
|
-
</ConsentManagerProvider>
|
|
93
|
-
```
|
|
94
|
-
|
|
95
|
-
A `nonce` set on an individual script definition still wins, so you can override a single vendor without changing the provider.
|
|
96
|
-
|
|
97
|
-
> 📝 **Note:**
|
|
98
|
-
> 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.
|
|
99
|
-
|
|
100
|
-
### Inline style attributes
|
|
101
|
-
|
|
102
|
-
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.
|
|
103
|
-
|
|
104
|
-
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:
|
|
105
|
-
|
|
106
|
-
```http
|
|
107
|
-
style-src 'self' 'nonce-abc123';
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
To keep the nonce requirement for stylesheets while still allowing style attributes, set `style-src-attr` explicitly:
|
|
111
|
-
|
|
112
|
-
```http
|
|
113
|
-
style-src 'self' 'nonce-abc123';
|
|
114
|
-
style-src-attr 'unsafe-inline';
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
> ⚠️ **Warning:**
|
|
118
|
-
> '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.
|
|
119
|
-
|
|
120
|
-
### Reading the nonce in the App Router
|
|
121
|
-
|
|
122
|
-
Next.js does not expose the request nonce to client components, so read it in a server component and pass it down. Generate the nonce in middleware, forward it on a request header, then hand it to the provider from your layout:
|
|
123
|
-
|
|
124
|
-
```ts title="middleware.ts"
|
|
125
|
-
import { NextResponse, type NextRequest } from 'next/server';
|
|
126
|
-
|
|
127
|
-
export function middleware(request: NextRequest) {
|
|
128
|
-
const nonce = crypto.randomUUID();
|
|
129
|
-
const isDev = process.env.NODE_ENV === 'development';
|
|
130
|
-
|
|
131
|
-
const csp = [
|
|
132
|
-
`default-src 'self'`,
|
|
133
|
-
// Next.js dev tooling (React Refresh and HMR) requires 'unsafe-eval'.
|
|
134
|
-
`script-src 'self' 'nonce-${nonce}'${isDev ? " 'unsafe-eval'" : ''}`,
|
|
135
|
-
`style-src 'self' 'nonce-${nonce}'`,
|
|
136
|
-
// Nonces cannot authorize inline style attributes — see above.
|
|
137
|
-
`style-src-attr 'unsafe-inline'`,
|
|
138
|
-
].join('; ');
|
|
139
|
-
|
|
140
|
-
const requestHeaders = new Headers(request.headers);
|
|
141
|
-
requestHeaders.set('x-nonce', nonce);
|
|
142
|
-
requestHeaders.set('Content-Security-Policy', csp);
|
|
143
|
-
|
|
144
|
-
const response = NextResponse.next({ request: { headers: requestHeaders } });
|
|
145
|
-
response.headers.set('Content-Security-Policy', csp);
|
|
146
|
-
|
|
147
|
-
return response;
|
|
148
|
-
}
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
> ⚠️ **Warning:**
|
|
152
|
-
> Set the same policy on both the forwarded request headers and the response. Next.js reads the nonce for its own runtime and hydration scripts from the Content-Security-Policy request header during rendering. Setting it only on the response leaves those scripts without a nonce, and the enforced policy then blocks them, so the page never hydrates.
|
|
153
|
-
|
|
154
|
-
```tsx title="app/layout.tsx"
|
|
155
|
-
import { headers } from 'next/headers';
|
|
156
|
-
import { ConsentManagerProvider } from '@c15t/nextjs';
|
|
157
|
-
|
|
158
|
-
export default async function RootLayout({
|
|
159
|
-
children,
|
|
160
|
-
}: {
|
|
161
|
-
children: React.ReactNode;
|
|
162
|
-
}) {
|
|
163
|
-
const nonce = (await headers()).get('x-nonce') ?? undefined;
|
|
164
|
-
|
|
165
|
-
return (
|
|
166
|
-
<html lang="en">
|
|
167
|
-
<body>
|
|
168
|
-
<ConsentManagerProvider options={{ mode: 'offline', nonce }}>
|
|
169
|
-
{children}
|
|
170
|
-
</ConsentManagerProvider>
|
|
171
|
-
</body>
|
|
172
|
-
</html>
|
|
173
|
-
);
|
|
174
|
-
}
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
## Legal Links
|
|
178
|
-
|
|
179
|
-
`legalLinks` defines the URLs shown in consent UI text (banner, dialog, and widget where applicable).
|
|
180
|
-
Configure only the links you want to expose.
|
|
181
|
-
|
|
182
|
-
```tsx
|
|
183
|
-
<ConsentManagerProvider
|
|
184
|
-
options={{
|
|
185
|
-
backendURL: 'https://your-instance.c15t.dev',
|
|
186
|
-
legalLinks: {
|
|
187
|
-
privacyPolicy: {
|
|
188
|
-
href: '/privacy',
|
|
189
|
-
target: '_self',
|
|
190
|
-
},
|
|
191
|
-
cookiePolicy: {
|
|
192
|
-
href: '/cookies',
|
|
193
|
-
target: '_self',
|
|
194
|
-
},
|
|
195
|
-
termsOfService: {
|
|
196
|
-
href: 'https://example.com/terms',
|
|
197
|
-
target: '_blank',
|
|
198
|
-
rel: 'noopener noreferrer',
|
|
199
|
-
label: 'Terms of Service',
|
|
200
|
-
},
|
|
201
|
-
},
|
|
202
|
-
}}
|
|
203
|
-
>
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
Notes:
|
|
207
|
-
|
|
208
|
-
* Omitting a key (for example `termsOfService`) hides that link.
|
|
209
|
-
* `label` overrides the translated text for that single link.
|
|
210
|
-
* Use `_self` for internal pages and `_blank` + `rel="noopener noreferrer"` for external pages.
|
|
211
|
-
* Control which of the configured links render in each component via the component's `legalLinks` prop.
|
|
212
|
-
|
|
213
|
-
## Overrides
|
|
214
|
-
|
|
215
|
-
`overrides` lets you force location/language signals instead of browser or network detection.
|
|
216
|
-
This is useful for QA, local development, and preview environments.
|
|
217
|
-
|
|
218
|
-
```tsx
|
|
219
|
-
<ConsentManagerProvider
|
|
220
|
-
options={{
|
|
221
|
-
backendURL: 'https://your-instance.c15t.dev',
|
|
222
|
-
overrides: {
|
|
223
|
-
country: 'DE',
|
|
224
|
-
region: 'BY',
|
|
225
|
-
language: 'de-DE',
|
|
226
|
-
},
|
|
227
|
-
}}
|
|
228
|
-
>
|
|
229
|
-
```
|
|
230
|
-
|
|
231
|
-
You can also override Global Privacy Control (GPC) behavior during testing:
|
|
232
|
-
|
|
233
|
-
```tsx
|
|
234
|
-
<ConsentManagerProvider
|
|
235
|
-
options={{
|
|
236
|
-
backendURL: 'https://your-instance.c15t.dev',
|
|
237
|
-
overrides: {
|
|
238
|
-
gpc: true,
|
|
239
|
-
},
|
|
240
|
-
}}
|
|
241
|
-
>
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
> ⚠️ **Warning:**
|
|
245
|
-
> Treat overrides as an environment/testing tool. Avoid hard-coding production overrides unless that behavior is intentional for your deployment.
|
|
246
|
-
|
|
247
|
-
## Policy Packs
|
|
248
|
-
|
|
249
|
-
In hosted mode (recommended), the backend resolves the correct policy automatically — no frontend policy config needed:
|
|
250
|
-
|
|
251
|
-
```tsx
|
|
252
|
-
<ConsentManagerProvider
|
|
253
|
-
options={{
|
|
254
|
-
backendURL: 'https://your-instance.c15t.dev',
|
|
255
|
-
}}
|
|
256
|
-
>
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
### Fallback: Offline Policies
|
|
260
|
-
|
|
261
|
-
When no backend is available, `ConsentManagerProvider` accepts `offlinePolicy.policyPacks` for local policy resolution during development, testing, previews, or temporary backend outages:
|
|
262
|
-
|
|
263
|
-
```tsx
|
|
264
|
-
<ConsentManagerProvider
|
|
265
|
-
options={{
|
|
266
|
-
mode: 'offline',
|
|
267
|
-
offlinePolicy: {
|
|
268
|
-
i18n: {
|
|
269
|
-
defaultProfile: 'default',
|
|
270
|
-
messages: {
|
|
271
|
-
default: {
|
|
272
|
-
translations: {
|
|
273
|
-
en: { cookieBanner: { title: 'Privacy choices' } },
|
|
274
|
-
},
|
|
275
|
-
},
|
|
276
|
-
qc: {
|
|
277
|
-
fallbackLanguage: 'fr',
|
|
278
|
-
translations: {
|
|
279
|
-
en: { cookieBanner: { title: 'Quebec Privacy Settings' } },
|
|
280
|
-
fr: { cookieBanner: { title: 'Paramètres de confidentialité du Québec' } },
|
|
281
|
-
},
|
|
282
|
-
},
|
|
283
|
-
},
|
|
284
|
-
},
|
|
285
|
-
policyPacks: [
|
|
286
|
-
{
|
|
287
|
-
id: 'qc_opt_in',
|
|
288
|
-
match: { regions: [{ country: 'CA', region: 'QC' }] },
|
|
289
|
-
i18n: { messageProfile: 'qc' },
|
|
290
|
-
consent: { model: 'opt-in', expiryDays: 365 },
|
|
291
|
-
ui: { mode: 'banner' },
|
|
292
|
-
},
|
|
293
|
-
{
|
|
294
|
-
id: 'default_world',
|
|
295
|
-
match: { isDefault: true },
|
|
296
|
-
consent: { model: 'none' },
|
|
297
|
-
ui: { mode: 'none' },
|
|
298
|
-
},
|
|
299
|
-
],
|
|
300
|
-
},
|
|
301
|
-
overrides: {
|
|
302
|
-
country: 'CA',
|
|
303
|
-
region: 'QC',
|
|
304
|
-
},
|
|
305
|
-
}}
|
|
306
|
-
>
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
Notes:
|
|
310
|
-
|
|
311
|
-
* `offlinePolicy` is only used in `offline` mode.
|
|
312
|
-
* Treat offline policies as a development/testing tool or resilience fallback, not the primary production source of truth.
|
|
313
|
-
* `offlinePolicy.i18n` lets offline mode mirror hosted `messageProfile` and profile-local `fallbackLanguage` behavior.
|
|
314
|
-
* Omitting `offlinePolicy.policyPacks` uses the built-in synthetic opt-in fallback banner. Hosted network fallback uses the same opt-in banner.
|
|
315
|
-
* `offlinePolicy: { policyPacks: [] }` is explicit no-banner mode.
|
|
316
|
-
* In hosted mode, backend `policyPacks` remain the source of truth — frontend offline policies never override a live backend decision.
|
|
317
|
-
|
|
318
|
-
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).
|
|
14
|
+
Follow [App Router](../app-router.md) or
|
|
15
|
+
[Pages Router](../pages-router.md) for the complete setup.
|
|
16
|
+
Keep `ConsentRoot` mounted across navigation and import the stylesheet once
|
|
17
|
+
at the app root.
|
|
319
18
|
|
|
320
19
|
## Props
|
|
321
20
|
|
|
322
|
-
|
|
|
323
|
-
|
|
324
|
-
|
|
|
325
|
-
|
|
|
326
|
-
|
|
327
|
-
|
|
21
|
+
| Prop | Purpose |
|
|
22
|
+
| ---------------- | --------------------------------------------------------------------------------------- |
|
|
23
|
+
| `state` | Visitor state or its promise from `resolveConsent`; use `{}` for browser initialization |
|
|
24
|
+
| `config` | Shared configuration from `defineConsentConfig` in `c15t.config.ts` |
|
|
25
|
+
| `backendURL` | Overrides `config.backendURL` |
|
|
26
|
+
| `scripts` | Consent-managed script configurations |
|
|
27
|
+
| `scriptLoader` | Script-loader options |
|
|
28
|
+
| `networkBlocker` | Network-blocker options, or `false` to disable it |
|
|
29
|
+
| `persistence` | Browser persistence options; defaults to `true` |
|
|
30
|
+
| `options` | Provider options such as styling, callbacks and an explicit `mode` override |
|
|
31
|
+
|
|
32
|
+
## Provider options
|
|
33
|
+
|
|
34
|
+
`ConsentRoot` passes `options` to its provider. Keep scripts, persistence and
|
|
35
|
+
network-blocker configuration in their top-level `ConsentRoot` props.
|
|
36
|
+
|
|
37
|
+
The provider owns initialization, persistence, script loading and subscriptions.
|
|
38
|
+
Changing its initial mode or prefetch configuration is not a supported way to
|
|
39
|
+
switch visitors or backends after mounting.
|
|
40
|
+
|
|
41
|
+
| Option | Purpose |
|
|
42
|
+
| --------------------- | --------------------------------------------------------------- |
|
|
43
|
+
| `mode` | Hosted, offline or custom transport factory |
|
|
44
|
+
| `callbacks` | Choice, permission and error events |
|
|
45
|
+
| `theme`, `components` | Theme tokens and component slot attributes |
|
|
46
|
+
| `presentation` | Prompt and preferences layout behavior |
|
|
47
|
+
| `i18n` | Languages and message overrides |
|
|
48
|
+
| `storageConfig` | Browser record storage configuration |
|
|
49
|
+
| `enabled` | Set false only when intentionally bypassing consent enforcement |
|
|
50
|
+
|
|
51
|
+
`enabled: false` grants categories and allows gated loading while suppressing
|
|
52
|
+
consent UI. It is not a way to fix failed initialization or hide a banner in
|
|
53
|
+
production.
|
|
54
|
+
|
|
55
|
+
## Listen for consent changes
|
|
56
|
+
|
|
57
|
+
`onChoiceRecorded` reports explicit accept, reject and save actions.
|
|
58
|
+
`onPermissionsChanged` also covers changes caused by policy, expiry or privacy
|
|
59
|
+
signals. Hydration and notice dismissal do not become explicit choices.
|
|
60
|
+
|
|
61
|
+
## When would I use ConsentProvider directly?
|
|
62
|
+
|
|
63
|
+
Use `ConsentProvider` from `c15t/next` when you need to manage the runtime and
|
|
64
|
+
transport yourself. For example, it accepts an externally owned `runtime`.
|
|
65
|
+
Its owner must start and dispose that runtime.
|
|
66
|
+
|
|
67
|
+
For standard Next.js setups, keep `ConsentRoot`. It supports
|
|
68
|
+
[browser initialization](../client-side.md) as well as
|
|
69
|
+
[server prefetch](../server-side.md).
|
|
70
|
+
|
|
71
|
+
## Clear data when consent is denied
|
|
72
|
+
|
|
73
|
+
Pass `clearOnRevocation` to `ConsentRoot`, or through the client provider's
|
|
74
|
+
`options`, to declare cookies and Web Storage keys by optional consent category.
|
|
75
|
+
Cleanup runs in the browser after policy resolution. The provider option is
|
|
76
|
+
initial-only. See [clear on revocation](../../../integrations/clear-on-revocation.md)
|
|
77
|
+
for examples, cookie scopes, and browser limits.
|