@c15t/scripts 2.2.0 → 3.0.0-alpha.0
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 +74 -48
- package/README.md +3 -3
- package/dist/e2e-test-utils.js +60 -24
- package/dist/engine/compile.js +45 -45
- package/dist/engine/runtime.js +119 -119
- package/dist/registry.js +186 -176
- package/dist/resolve.js +12 -12
- package/dist/vendors/_shared/attributes.js +5 -5
- package/dist/vendors/_shared/google-consent.js +10 -10
- package/dist/vendors/_shared/install-builders.js +9 -9
- package/dist/vendors/_shared/script-url.js +12 -12
- package/dist/vendors/ads-and-pixels/linkedin-insights.js +16 -16
- package/dist/vendors/ads-and-pixels/meta-pixel.js +82 -82
- package/dist/vendors/ads-and-pixels/microsoft-uet.js +57 -57
- package/dist/vendors/ads-and-pixels/openai-pixel.js +88 -0
- package/dist/vendors/ads-and-pixels/reddit-pixel.js +39 -39
- package/dist/vendors/ads-and-pixels/snapchat-pixel.js +25 -25
- package/dist/vendors/ads-and-pixels/tiktok-pixel.js +31 -31
- package/dist/vendors/ads-and-pixels/x-pixel.js +17 -17
- package/dist/vendors/analytics/adobe-analytics.js +17 -17
- package/dist/vendors/analytics/ahrefs-analytics.js +8 -8
- package/dist/vendors/analytics/amplitude.js +39 -39
- package/dist/vendors/analytics/clearbit.js +11 -11
- package/dist/vendors/analytics/cloudflare-web-analytics.js +13 -13
- package/dist/vendors/analytics/databuddy.js +45 -45
- package/dist/vendors/analytics/fathom-analytics.js +15 -15
- package/dist/vendors/analytics/google-tag.js +23 -23
- package/dist/vendors/analytics/heap.js +37 -37
- package/dist/vendors/analytics/hightouch.js +30 -30
- package/dist/vendors/analytics/hotjar.js +14 -14
- package/dist/vendors/analytics/logrocket.js +24 -24
- package/dist/vendors/analytics/matomo-analytics.js +51 -51
- package/dist/vendors/analytics/microsoft-clarity.js +31 -31
- package/dist/vendors/analytics/mixpanel-analytics.js +31 -31
- package/dist/vendors/analytics/pirsch.js +27 -27
- package/dist/vendors/analytics/plausible-analytics.js +24 -24
- package/dist/vendors/analytics/posthog.js +84 -79
- package/dist/vendors/analytics/promptwatch.js +8 -8
- package/dist/vendors/analytics/rudderstack.js +50 -50
- package/dist/vendors/analytics/rybbit-analytics.js +30 -30
- package/dist/vendors/analytics/segment.js +16 -16
- package/dist/vendors/analytics/umami-analytics.js +16 -16
- package/dist/vendors/analytics/vercel-analytics.js +22 -22
- package/dist/vendors/functional/crisp.js +49 -51
- package/dist/vendors/functional/intercom.js +18 -18
- package/dist/vendors/tag-managers/google-tag-manager.js +20 -20
- package/dist-types/__tests__/helpers.d.ts +10 -10
- package/dist-types/engine/compile.d.ts +2 -2
- package/dist-types/engine/runtime.d.ts +3 -3
- package/dist-types/registry.d.ts +182 -173
- package/dist-types/resolve.d.ts +2 -2
- package/dist-types/types.d.ts +2 -2
- package/dist-types/vendors/_shared/attributes.d.ts +2 -2
- package/dist-types/vendors/_shared/google-consent.d.ts +2 -2
- package/dist-types/vendors/_shared/install-builders.d.ts +1 -1
- package/dist-types/vendors/_shared/script-url.d.ts +6 -6
- package/dist-types/vendors/ads-and-pixels/linkedin-insights.d.ts +14 -14
- package/dist-types/vendors/ads-and-pixels/meta-pixel.d.ts +27 -27
- package/dist-types/vendors/ads-and-pixels/microsoft-uet.d.ts +40 -40
- package/dist-types/vendors/ads-and-pixels/openai-pixel.d.ts +211 -0
- package/dist-types/vendors/ads-and-pixels/reddit-pixel.d.ts +28 -29
- package/dist-types/vendors/ads-and-pixels/snapchat-pixel.d.ts +23 -23
- package/dist-types/vendors/ads-and-pixels/tiktok-pixel.d.ts +22 -22
- package/dist-types/vendors/ads-and-pixels/x-pixel.d.ts +15 -15
- package/dist-types/vendors/analytics/adobe-analytics.d.ts +3 -3
- package/dist-types/vendors/analytics/ahrefs-analytics.d.ts +5 -5
- package/dist-types/vendors/analytics/amplitude.d.ts +24 -24
- package/dist-types/vendors/analytics/clearbit.d.ts +5 -5
- package/dist-types/vendors/analytics/cloudflare-web-analytics.d.ts +6 -6
- package/dist-types/vendors/analytics/databuddy.d.ts +34 -31
- package/dist-types/vendors/analytics/fathom-analytics.d.ts +8 -8
- package/dist-types/vendors/analytics/google-tag.d.ts +17 -17
- package/dist-types/vendors/analytics/heap.d.ts +17 -17
- package/dist-types/vendors/analytics/hightouch.d.ts +15 -15
- package/dist-types/vendors/analytics/hotjar.d.ts +9 -9
- package/dist-types/vendors/analytics/logrocket.d.ts +11 -11
- package/dist-types/vendors/analytics/matomo-analytics.d.ts +3 -3
- package/dist-types/vendors/analytics/microsoft-clarity.d.ts +12 -13
- package/dist-types/vendors/analytics/mixpanel-analytics.d.ts +20 -20
- package/dist-types/vendors/analytics/pirsch.d.ts +10 -10
- package/dist-types/vendors/analytics/plausible-analytics.d.ts +13 -13
- package/dist-types/vendors/analytics/posthog.d.ts +35 -32
- package/dist-types/vendors/analytics/promptwatch.d.ts +5 -5
- package/dist-types/vendors/analytics/rudderstack.d.ts +16 -16
- package/dist-types/vendors/analytics/rybbit-analytics.d.ts +15 -15
- package/dist-types/vendors/analytics/segment.d.ts +11 -11
- package/dist-types/vendors/analytics/umami-analytics.d.ts +9 -9
- package/dist-types/vendors/analytics/vercel-analytics.d.ts +13 -13
- package/dist-types/vendors/functional/crisp.d.ts +9 -9
- package/dist-types/vendors/functional/intercom.d.ts +12 -12
- package/dist-types/vendors/tag-managers/google-tag-manager.d.ts +16 -16
- package/docs/README.md +74 -48
- 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/javascript/script-loader.md +30 -339
- package/docs/frameworks/next/script-loader.md +134 -467
- package/docs/frameworks/react/script-loader.md +35 -535
- 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/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/package.json +85 -78
- package/readme.json +2 -2
- package/dist/e2e-test-utils.cjs +0 -166
- package/dist/engine/compile.cjs +0 -130
- package/dist/engine/runtime.cjs +0 -475
- package/dist/registry.cjs +0 -423
- package/dist/resolve.cjs +0 -71
- package/dist/types.cjs +0 -69
- package/dist/vendors/_shared/attributes.cjs +0 -55
- package/dist/vendors/_shared/google-consent.cjs +0 -69
- package/dist/vendors/_shared/install-builders.cjs +0 -59
- package/dist/vendors/_shared/script-url.cjs +0 -78
- package/dist/vendors/ads-and-pixels/linkedin-insights.cjs +0 -89
- package/dist/vendors/ads-and-pixels/meta-pixel.cjs +0 -206
- package/dist/vendors/ads-and-pixels/microsoft-uet.cjs +0 -151
- package/dist/vendors/ads-and-pixels/reddit-pixel.cjs +0 -151
- package/dist/vendors/ads-and-pixels/snapchat-pixel.cjs +0 -131
- package/dist/vendors/ads-and-pixels/tiktok-pixel.cjs +0 -130
- package/dist/vendors/ads-and-pixels/x-pixel.cjs +0 -92
- package/dist/vendors/analytics/adobe-analytics.cjs +0 -90
- package/dist/vendors/analytics/ahrefs-analytics.cjs +0 -68
- package/dist/vendors/analytics/amplitude.cjs +0 -193
- package/dist/vendors/analytics/clearbit.cjs +0 -69
- package/dist/vendors/analytics/cloudflare-web-analytics.cjs +0 -73
- package/dist/vendors/analytics/databuddy.cjs +0 -144
- package/dist/vendors/analytics/fathom-analytics.cjs +0 -76
- package/dist/vendors/analytics/google-tag.cjs +0 -107
- package/dist/vendors/analytics/heap.cjs +0 -181
- package/dist/vendors/analytics/hightouch.cjs +0 -153
- package/dist/vendors/analytics/hotjar.cjs +0 -85
- package/dist/vendors/analytics/logrocket.cjs +0 -99
- package/dist/vendors/analytics/matomo-analytics.cjs +0 -232
- package/dist/vendors/analytics/microsoft-clarity.cjs +0 -138
- package/dist/vendors/analytics/mixpanel-analytics.cjs +0 -134
- package/dist/vendors/analytics/pirsch.cjs +0 -108
- package/dist/vendors/analytics/plausible-analytics.cjs +0 -122
- package/dist/vendors/analytics/posthog.cjs +0 -236
- package/dist/vendors/analytics/promptwatch.cjs +0 -70
- package/dist/vendors/analytics/rudderstack.cjs +0 -227
- package/dist/vendors/analytics/rybbit-analytics.cjs +0 -104
- package/dist/vendors/analytics/segment.cjs +0 -97
- package/dist/vendors/analytics/umami-analytics.cjs +0 -80
- package/dist/vendors/analytics/vercel-analytics.cjs +0 -94
- package/dist/vendors/functional/crisp.cjs +0 -143
- package/dist/vendors/functional/intercom.cjs +0 -89
- package/dist/vendors/tag-managers/google-tag-manager.cjs +0 -100
- package/docs/shared/react/guides/script-loader.md +0 -311
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Upgrade to v3 policies
|
|
3
|
+
description: Migrate policy configuration, consent records, callbacks, and
|
|
4
|
+
custom transports to the v3 policy system.
|
|
5
|
+
group: reference
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Start with a policy rule
|
|
9
|
+
|
|
10
|
+
```ts
|
|
11
|
+
import { policyRulePresets } from '@c15t/schema';
|
|
12
|
+
import { offline } from '@c15t/react';
|
|
13
|
+
|
|
14
|
+
const mode = offline({
|
|
15
|
+
policyRules: [policyRulePresets.europeOptIn()],
|
|
16
|
+
});
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Pass `mode` to `ConsentProvider`. For a backend integration, configure
|
|
20
|
+
`policyRules` on the backend and use `hosted({ url })` in the provider. Follow the
|
|
21
|
+
[React quickstart](https://c15t.com/docs/frameworks/react/quickstart),
|
|
22
|
+
[Next.js quickstart](https://c15t.com/docs/frameworks/next/quickstart), or
|
|
23
|
+
[JavaScript quickstart](https://c15t.com/docs/frameworks/javascript/quickstart) for a complete
|
|
24
|
+
integration.
|
|
25
|
+
|
|
26
|
+
The CLI no longer offers `offline-add-policy-packs`, which generated v2
|
|
27
|
+
configuration. For offline integrations, configure `offline({ policyRules })`
|
|
28
|
+
as shown above.
|
|
29
|
+
|
|
30
|
+
Replace legacy `policyPacks` and nested `consent` configuration with rules:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import type { PolicyRule } from '@c15t/schema';
|
|
34
|
+
|
|
35
|
+
const policyRules = [
|
|
36
|
+
{
|
|
37
|
+
id: 'default-opt-in',
|
|
38
|
+
match: { fallback: true },
|
|
39
|
+
model: 'opt-in',
|
|
40
|
+
prompt: 'choice',
|
|
41
|
+
categories: ['measurement', 'marketing'],
|
|
42
|
+
scopeMode: 'strict',
|
|
43
|
+
},
|
|
44
|
+
] satisfies PolicyRule[];
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
`model` controls permission defaults. `prompt` controls whether the visitor must
|
|
48
|
+
make a choice, dismiss a notice, or see no prompt. Opt-in and IAB models require
|
|
49
|
+
`prompt: 'choice'`. Opt-out supports `choice`, `notice`, and `none`. The `none`
|
|
50
|
+
model permits optional categories in scope, allows only `prompt: 'none'`, owes
|
|
51
|
+
no rights, and renders no consent UI. v2's `none` model maps to it directly.
|
|
52
|
+
|
|
53
|
+
When `categories` selects only some optional categories, you must set
|
|
54
|
+
`scopeMode` explicitly. A strict scope blocks categories outside the rule. A permissive scope allows
|
|
55
|
+
those categories unless another restriction applies. An omitted scope, `['*']`,
|
|
56
|
+
or a list containing only `necessary` expands to the default optional categories.
|
|
57
|
+
`necessary` is always permitted.
|
|
58
|
+
|
|
59
|
+
`offline()` without `policyRules` resolves `recommendedPolicyRules()`, whose
|
|
60
|
+
Europe rule also matches a visitor with no country. A known US country with a
|
|
61
|
+
missing state uses US opt-out with GPC and persistent preferences; a missing
|
|
62
|
+
Canadian province stays strict opt-in. The last rule is `none` for other known
|
|
63
|
+
unmatched locations. Resolution exposes `matched`, `no-match`,
|
|
64
|
+
`unconfigured`, or `failed`; while nothing has matched, optional categories stay
|
|
65
|
+
denied and no consent surface renders. A missing or malformed policy never grants
|
|
66
|
+
optional permissions by itself.
|
|
67
|
+
|
|
68
|
+
## Read the state you need
|
|
69
|
+
|
|
70
|
+
| Purpose | Snapshot field | React hook |
|
|
71
|
+
| ----------------------------------------------- | ---------------------- | --------------------------------------- |
|
|
72
|
+
| Gate scripts and optional features | `effectivePermissions` | `useConsent(category)`, `useConsents()` |
|
|
73
|
+
| Inspect recorded choices and confirmation times | `explicitChoice` | `useExplicitChoice()` |
|
|
74
|
+
| Decide whether to prompt | `promptRequirement` | `usePromptRequirement()` |
|
|
75
|
+
| Inspect the resolved rule | `policyRule` | `usePolicyRule()` |
|
|
76
|
+
| Inspect matching or failure | `resolution` | `usePolicyResolution()` |
|
|
77
|
+
|
|
78
|
+
An effective permission is not evidence of a grant. Under an opt-out rule it can
|
|
79
|
+
be true before a visitor acts. A notice dismissal updates `noticeDismissal` and
|
|
80
|
+
does not record consent. Global Privacy Control updates privacy signals and
|
|
81
|
+
configured opt-out directives without turning a browser signal into a choice.
|
|
82
|
+
|
|
83
|
+
## Replace choice callbacks
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
<ConsentProvider
|
|
87
|
+
options={{
|
|
88
|
+
mode,
|
|
89
|
+
callbacks: {
|
|
90
|
+
onChoiceRecorded(event) {
|
|
91
|
+
console.log('Visitor recorded a choice', event);
|
|
92
|
+
},
|
|
93
|
+
onPermissionsChanged(event) {
|
|
94
|
+
console.log('Effective permissions changed', event);
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
}}
|
|
98
|
+
>
|
|
99
|
+
{children}
|
|
100
|
+
</ConsentProvider>
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Replace `onConsentSet` with `onChoiceRecorded` for explicit accept, reject, or
|
|
104
|
+
save actions. Use `onPermissionsChanged` for permission changes caused by a
|
|
105
|
+
choice, expiry, policy update, or privacy signal. Provider callbacks no longer
|
|
106
|
+
include `onBannerFetched`; use the resolved policy and pending state to render
|
|
107
|
+
loading UI.
|
|
108
|
+
|
|
109
|
+
Only `kernel.commands.save()` creates an explicit choice. `save('all')` accepts,
|
|
110
|
+
`save('none')` rejects, and `save({ marketing: false })` confirms only marketing.
|
|
111
|
+
A partial save keeps the other categories' confirmation times. Use
|
|
112
|
+
`commands.dismissNotice()` for the notice action and `kernel.hydrate()` to apply
|
|
113
|
+
validated records without recording an action.
|
|
114
|
+
|
|
115
|
+
## Keep existing storage
|
|
116
|
+
|
|
117
|
+
The reader accepts valid v2 storage and translates it into per-category receipts.
|
|
118
|
+
It does not rewrite storage on startup. Existing denials continue to restrict
|
|
119
|
+
permissions; expired or incompatible positive receipts cannot restore grants.
|
|
120
|
+
The next explicit action writes the v3 record. Notice dismissal and privacy
|
|
121
|
+
opt-out directives have separate records.
|
|
122
|
+
|
|
123
|
+
Pass server-prepared `initialRecords`, `initialPolicyResolution`, and `now`
|
|
124
|
+
through the adapter's prefetch configuration. Do not rebuild consent from a
|
|
125
|
+
boolean `hasConsented` or copy effective permissions into explicit choice records.
|
|
126
|
+
Pending prefetch results cannot restore records after a clear or overwrite a
|
|
127
|
+
newer choice.
|
|
128
|
+
|
|
129
|
+
## Update custom transports and backend clients
|
|
130
|
+
|
|
131
|
+
Use `KernelTransport` from `@c15t/core/transports`. Init returns a versioned
|
|
132
|
+
`policyResolution` with a matched rule and fingerprints, or an explicit
|
|
133
|
+
non-matched outcome. Use `mapInitOutputToInitResponse` for an HTTP init payload.
|
|
134
|
+
Do not return legacy `policy` or `policyDecision` fields.
|
|
135
|
+
|
|
136
|
+
Save requests contain the explicit choice and the categories confirmed by this
|
|
137
|
+
action. Return a `SaveResult` with `ok`; optional identity and record methods
|
|
138
|
+
must preserve the same receipt format. Forward the policy contract headers when
|
|
139
|
+
implementing an HTTP proxy. Keep client, schema, backend, and framework adapters
|
|
140
|
+
on compatible v3 versions.
|
|
141
|
+
|
|
142
|
+
Use the supplied hosted or manifest transports to capture policy evidence for
|
|
143
|
+
saves and retries. They preserve the action's policy, location, language, and
|
|
144
|
+
privacy signal inputs. A stale policy assertion is an error; it must not silently
|
|
145
|
+
save under a different rule. See the
|
|
146
|
+
[backend endpoint reference](https://c15t.com/docs/self-host/api/endpoints) for wire fields.
|
|
147
|
+
|
|
148
|
+
## Shared runtime ownership
|
|
149
|
+
|
|
150
|
+
Astro and SvelteKit can create a runtime outside a component tree with
|
|
151
|
+
`createConsentRuntime` from `@c15t/core/runtime`. Pass that runtime to a
|
|
152
|
+
framework provider with its `runtime` prop. The owner calls `start()` after
|
|
153
|
+
mount and `dispose()` when the page no longer needs it. Borrowing providers
|
|
154
|
+
subscribe to the kernel and render UI without initializing or disposing it.
|
|
155
|
+
|
|
156
|
+
Runtime construction preserves the prepared server snapshot. Storage reads,
|
|
157
|
+
privacy-signal activation and script loading begin on `start()`. Pass server
|
|
158
|
+
records through `prefetch.initialRecords` with their evaluation time to keep
|
|
159
|
+
the first browser render consistent with the server. `runtime.clearRecords()`
|
|
160
|
+
clears both persisted and in-memory records.
|
|
161
|
+
|
|
162
|
+
Runtime callbacks use `onChoiceRecorded`, `onPermissionsChanged` and
|
|
163
|
+
`onError`. Hydrating records does not report a new visitor choice.
|
|
164
|
+
|
|
165
|
+
Astro's serializable offline descriptor accepts `policyRules`, just like the
|
|
166
|
+
other adapters' offline factories. Configure a preset or explicit rules;
|
|
167
|
+
omitting them keeps the conservative fallback.
|
|
168
|
+
|
|
169
|
+
## Presentation corrections
|
|
170
|
+
|
|
171
|
+
Use `blocking` for backdrop, scroll locking and focus trapping together.
|
|
172
|
+
Choice banners default to non-blocking, choice walls always block, and notices
|
|
173
|
+
never block. A notice configured as a wall falls back to a floating card.
|
|
174
|
+
Preferences remain centered; `variant` and `position` apply only to prompts.
|
|
175
|
+
|
|
176
|
+
Replace reads of `uncoveredRights` with `preferenceControls`. The latter is a
|
|
177
|
+
list of additional preferences buttons recommended for the stock UI. It does
|
|
178
|
+
not verify disclosure or persistent access to policy rights.
|
|
179
|
+
|
|
180
|
+
Notice acknowledgement uses `common.acknowledge`, falling back to
|
|
181
|
+
`common.dismiss` for older translation bundles. It does not record a choice.
|
|
182
|
+
|
|
183
|
+
## Astro notice acknowledgement
|
|
184
|
+
|
|
185
|
+
```astro
|
|
186
|
+
---
|
|
187
|
+
import ConsentBanner from '@c15t/astro/components/consent-banner.astro';
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
<ConsentBanner dismissButtonText="Got it" />
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
Astro's `ConsentBanner` accepts `dismissButtonText` as an optional string. It
|
|
194
|
+
labels the notice acknowledgement button, which defaults to
|
|
195
|
+
`common.acknowledge` and falls back to `common.dismiss` in older translation
|
|
196
|
+
bundles. Acknowledging a notice preserves the visitor's consent choices.
|
|
197
|
+
|
|
198
|
+
## IAB blocking behavior
|
|
199
|
+
|
|
200
|
+
IAB banners and dialogs use the same `presentation.prompt.blocking` and
|
|
201
|
+
`presentation.preferences.blocking` settings as the other consent components.
|
|
202
|
+
A blocking surface shows a backdrop, traps focus and locks page scrolling.
|
|
203
|
+
Explicit `blocking` values take precedence over deprecated `scrollLock` and
|
|
204
|
+
`trapFocus` options. IAB components stay hidden without a matched policy,
|
|
205
|
+
including when a dialog receives `open={true}`.
|
|
206
|
+
|
|
207
|
+
The React consent dialog still blocks pointer interaction with the page when
|
|
208
|
+
`blocking` is true and you hide its backdrop with `overlay={false}`.
|
|
209
|
+
|
|
210
|
+
Legacy prompt options now control the whole blocking behavior. For example,
|
|
211
|
+
`scrollLock: true` alone enables a backdrop and focus trapping as well as
|
|
212
|
+
scroll locking. Set `blocking: false` explicitly for a non-modal banner.
|
|
213
|
+
|
|
214
|
+
Custom dialog backdrops follow the same rule. A dialog resolved as non-blocking
|
|
215
|
+
omits both the default backdrop and a supplied `overlay`. To retain a custom
|
|
216
|
+
backdrop when migrating from `trapFocus: false`, set
|
|
217
|
+
`presentation.preferences.blocking: true` and keep your `overlay` prop.
|
|
218
|
+
|
|
219
|
+
## Next.js and TanStack Start renames
|
|
220
|
+
|
|
221
|
+
These names changed without deprecated aliases. `defineConsentConfig`,
|
|
222
|
+
`ConsentConfig` (the URL config) and `ConsentProvider` from `@c15t/react` are
|
|
223
|
+
unchanged.
|
|
224
|
+
|
|
225
|
+
Next.js (`c15t/next`, `c15t/next/server`, `c15t/next/pages`):
|
|
226
|
+
|
|
227
|
+
| v2 | v3 |
|
|
228
|
+
| --------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
|
|
229
|
+
| `ConsentBoundary` | `ConsentRoot` |
|
|
230
|
+
| `ConsentBoundaryProps` | `ConsentRootProps` |
|
|
231
|
+
| `config={initialConsent}` (the visitor's resolved state) | `state={...}` |
|
|
232
|
+
| `consent={consentConfig}` (the `defineConsentConfig` result) | `config={consentConfig}` |
|
|
233
|
+
| `prefetchInitialConsent(options)` | `resolveConsent(options)` with `config` or `backendURL` |
|
|
234
|
+
| `readInitialConsentConfig(options)` | `resolveConsent(options)` without `config` or `backendURL` |
|
|
235
|
+
| `InitialConsentConfig`, and `KernelConfig` where it named the returned value | `ConsentState` |
|
|
236
|
+
| `PrefetchInitialConsentOptions` | `ResolveConsentOptions` |
|
|
237
|
+
| `ReadInitialConsentConfigOptions` | `ConsentRequestOptions` |
|
|
238
|
+
| Pages Router `readInitialConsentConfig(req, opts)` and `prefetchInitialConsent({ req, ... })` | `resolveConsent({ req, ... })` |
|
|
239
|
+
|
|
240
|
+
TanStack Start (`c15t/tanstack-start`, `c15t/tanstack-start/server`):
|
|
241
|
+
|
|
242
|
+
| v2 | v3 |
|
|
243
|
+
| ------------------------------------- | ---------------------------------------------- |
|
|
244
|
+
| `ConsentBoundary` | `ConsentRoot` |
|
|
245
|
+
| `config={config}` | `state={state}` |
|
|
246
|
+
| `ConsentConfig` (the returned state) | `ConsentState` |
|
|
247
|
+
| `prefetchInitialConsent` | `resolveConsent(options)` with `backendURL` |
|
|
248
|
+
| `readInitialConsentConfig` | `resolveConsent(options)` without `backendURL` |
|
|
249
|
+
| `createConsentConfigHandler(options)` | `createConsentStateHandler(options)` |
|
|
250
|
+
| `mergeInitIntoConsentConfig` | `mergeInitIntoConsentState` |
|
|
251
|
+
|
|
252
|
+
`consentLoaderOptions`, `backendURL`, `initRoute` and `DEFAULT_INIT_ROUTE` are
|
|
253
|
+
unchanged.
|
|
254
|
+
|
|
255
|
+
## Next.js RSC banner removal
|
|
256
|
+
|
|
257
|
+
The `@c15t/nextjs/rsc` entry (`c15t/next/rsc`) and its `RscConsentBanner`,
|
|
258
|
+
`RscBannerGate` and `RscBannerActions` exports are gone. Imports of that
|
|
259
|
+
entry now fail to resolve. Use the regular banner for server rendering.
|
|
260
|
+
The retained benchmark results showed slightly faster banner visibility and
|
|
261
|
+
interaction for the experimental shell, so this removal should not be read
|
|
262
|
+
as a performance improvement.
|
|
263
|
+
|
|
264
|
+
Replace `<RscConsentBanner config={config} />` with `<ConsentBanner />` inside
|
|
265
|
+
the same `ConsentRoot`, importing it from `c15t/next` when you use the
|
|
266
|
+
umbrella package or from `@c15t/nextjs` when you depend on the scoped package
|
|
267
|
+
directly. With an awaited `resolveConsent` result, the server renders
|
|
268
|
+
the banner into the response, which is what the RSC variant was for. Move
|
|
269
|
+
`presentation` to `options.presentation` on `ConsentRoot`.
|
|
270
|
+
|
|
271
|
+
Two defaults differ from the removed shell. It rendered no branding link, so
|
|
272
|
+
pass `hideBranding` to keep that. It also styled only its root and action row
|
|
273
|
+
(through the stock `ConsentBanner.Root` and `PolicyActions`) and left the
|
|
274
|
+
card, title, description, footer and buttons without base classes, whereas
|
|
275
|
+
`ConsentBanner` merges the stock styles into every part. If that changes a
|
|
276
|
+
custom layout, do not reach for `noStyle` on the whole banner, which also
|
|
277
|
+
drops the root positioning and action-row layout the old shell kept; compose
|
|
278
|
+
the compound parts instead and pass `noStyle` only to the parts you styled
|
|
279
|
+
yourself.
|
|
280
|
+
|
|
281
|
+
`ConsentBanner` has no `classNames` or `children` props. Move each legacy
|
|
282
|
+
`classNames` key to the `ConsentRoot` `options.components` slots, which take
|
|
283
|
+
`{ className }`:
|
|
284
|
+
|
|
285
|
+
| `classNames` key | Replacement |
|
|
286
|
+
| ------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
287
|
+
| `root`, `card`, `title`, `footer` | `components.banner.root`, `.card`, `.title`, `.footer` |
|
|
288
|
+
| `description` | `components.description.banner` |
|
|
289
|
+
| `rights`, `rightLink` | `components.banner.rights`, `components.banner.rightLink` |
|
|
290
|
+
| `acceptButton`, `rejectButton`, `customizeButton`, `dismissButton` | No per-button slot. Use `components.button.primary` / `.secondary` for shared styles, or target `[data-action="accept"]`, `[data-action="reject"]`, `[data-action="customize"]` and `[data-action="dismiss"]` in CSS. |
|
|
291
|
+
|
|
292
|
+
Custom `children`, and any direct use of `RscBannerGate` or
|
|
293
|
+
`RscBannerActions`, map to the compound parts of `ConsentBanner` in a Client
|
|
294
|
+
Component. `RscBannerGate` becomes `ConsentBanner.Root`, which mounts only
|
|
295
|
+
while the policy owes a prompt and reopens on expiry. Remove the gate
|
|
296
|
+
`prompt` and `model` props; the root derives `data-prompt` and `data-model`
|
|
297
|
+
from the `ConsentRoot` policy. Rename `title` to `aria-label` to preserve its
|
|
298
|
+
accessible label. Keep `children`, `className`, `variant`, `position` and
|
|
299
|
+
`blocking` on the root. Add `disableAnimation` and `trapFocus={false}` to
|
|
300
|
+
retain the old gate defaults.
|
|
301
|
+
|
|
302
|
+
`RscBannerActions`
|
|
303
|
+
becomes `ConsentBanner.PolicyActions`, which renders the rights links and the
|
|
304
|
+
action row the policy requires; `ConsentBanner.Rights`, `RightLink`, `Footer`,
|
|
305
|
+
`FooterSubGroup` and the four buttons are available for finer control.
|
|
306
|
+
`PolicyActions` takes none of the old `acceptLabel`, `rejectLabel`,
|
|
307
|
+
`customizeLabel`, `dismissLabel`, `rightLabels` or `classNames` props: set
|
|
308
|
+
labels through the provider `i18n` translation overrides (`common.acceptAll`,
|
|
309
|
+
`common.rejectAll`, `common.customize`, `common.acknowledge`, `rights.*`), or
|
|
310
|
+
render `ConsentBanner.AcceptButton` and the other buttons with your own
|
|
311
|
+
children; `renderAction` on `PolicyActions` replaces one button; classes move
|
|
312
|
+
to the `components` slots listed in the table. Place the former `children`
|
|
313
|
+
inside `ConsentBanner.Card`:
|
|
314
|
+
|
|
315
|
+
```tsx title="components/banner.tsx"
|
|
316
|
+
'use client';
|
|
317
|
+
|
|
318
|
+
import { ConsentBanner } from 'c15t/next';
|
|
319
|
+
|
|
320
|
+
export function Banner() {
|
|
321
|
+
return (
|
|
322
|
+
<ConsentBanner.Root>
|
|
323
|
+
<ConsentBanner.Card>
|
|
324
|
+
<ConsentBanner.Header>
|
|
325
|
+
<ConsentBanner.Title />
|
|
326
|
+
<ConsentBanner.Description />
|
|
327
|
+
</ConsentBanner.Header>
|
|
328
|
+
<a href="/privacy">Privacy policy</a>
|
|
329
|
+
<ConsentBanner.PolicyActions />
|
|
330
|
+
</ConsentBanner.Card>
|
|
331
|
+
</ConsentBanner.Root>
|
|
332
|
+
);
|
|
333
|
+
}
|
|
334
|
+
```
|