@c15t/scripts 3.0.0-alpha.1 → 3.0.0-alpha.3
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 +129 -59
- package/README.md +8 -29
- package/SKILL.md +33 -0
- package/dist/adobe-analytics.js +2 -0
- package/dist/ahrefs-analytics.js +2 -0
- package/dist/amplitude.js +2 -0
- package/dist/clearbit.js +2 -0
- package/dist/cloudflare-web-analytics.js +2 -0
- package/dist/cloudflare-zaraz.js +2 -0
- package/dist/crisp.js +2 -0
- package/dist/databuddy.js +2 -0
- package/dist/e2e-test-utils.js +2 -137
- package/dist/engine/compile.js +2 -89
- package/dist/engine/runtime.js +2 -448
- package/dist/events.js +2 -0
- package/dist/fathom-analytics.js +2 -0
- package/dist/front-chat.js +2 -0
- package/dist/google-tag-manager.js +2 -0
- package/dist/google-tag.js +2 -0
- package/dist/heap.js +2 -0
- package/dist/hightouch.js +2 -0
- package/dist/hotjar.js +2 -0
- package/dist/intercom.js +2 -0
- package/dist/klaviyo.js +2 -0
- package/dist/linkedin-insights.js +2 -0
- package/dist/logrocket.js +2 -0
- package/dist/matomo-analytics.js +2 -0
- package/dist/meta-pixel.js +2 -0
- package/dist/microsoft-clarity.js +2 -0
- package/dist/microsoft-uet.js +2 -0
- package/dist/mixpanel-analytics.js +2 -0
- package/dist/one-dollar-stats.js +2 -0
- package/dist/openai-pixel.js +2 -0
- package/dist/pinterest-tag.js +2 -0
- package/dist/pirsch.js +2 -0
- package/dist/plausible-analytics.js +2 -0
- package/dist/posthog.js +2 -0
- package/dist/promptwatch.js +2 -0
- package/dist/reddit-pixel.js +2 -0
- package/dist/registry.js +2 -392
- package/dist/resolve.js +2 -33
- package/dist/rudderstack.js +2 -0
- package/dist/rybbit-analytics.js +2 -0
- package/dist/segment.js +2 -0
- package/dist/snapchat-pixel.js +2 -0
- package/dist/tiktok-pixel.js +2 -0
- package/dist/types.js +2 -16
- package/dist/umami-analytics.js +2 -0
- package/dist/vendors/_shared/attributes.js +2 -14
- package/dist/vendors/_shared/google-consent.js +2 -27
- package/dist/vendors/_shared/install-builders.js +2 -21
- package/dist/vendors/_shared/required-id.js +2 -0
- package/dist/vendors/_shared/script-url.js +2 -28
- package/dist/vendors/ads-and-pixels/linkedin-insights.js +2 -48
- package/dist/vendors/ads-and-pixels/meta-pixel.js +2 -153
- package/dist/vendors/ads-and-pixels/microsoft-uet.js +2 -110
- package/dist/vendors/ads-and-pixels/openai-pixel.js +2 -88
- package/dist/vendors/ads-and-pixels/pinterest-tag.js +2 -0
- package/dist/vendors/ads-and-pixels/reddit-pixel.js +2 -107
- package/dist/vendors/ads-and-pixels/snapchat-pixel.js +2 -87
- package/dist/vendors/ads-and-pixels/tiktok-pixel.js +2 -89
- package/dist/vendors/ads-and-pixels/x-pixel.js +2 -48
- package/dist/vendors/analytics/adobe-analytics.js +2 -49
- package/dist/vendors/analytics/ahrefs-analytics.js +2 -27
- package/dist/vendors/analytics/amplitude.js +2 -134
- package/dist/vendors/analytics/clearbit.js +2 -28
- package/dist/vendors/analytics/cloudflare-web-analytics.js +2 -32
- package/dist/vendors/analytics/databuddy.js +2 -103
- package/dist/vendors/analytics/fathom-analytics.js +2 -35
- package/dist/vendors/analytics/google-tag.js +2 -66
- package/dist/vendors/analytics/heap.js +2 -134
- package/dist/vendors/analytics/hightouch.js +2 -109
- package/dist/vendors/analytics/hotjar.js +2 -44
- package/dist/vendors/analytics/logrocket.js +2 -58
- package/dist/vendors/analytics/matomo-analytics.js +2 -191
- package/dist/vendors/analytics/microsoft-clarity.js +2 -100
- package/dist/vendors/analytics/mixpanel-analytics.js +2 -93
- package/dist/vendors/analytics/one-dollar-stats.js +2 -0
- package/dist/vendors/analytics/pirsch.js +2 -67
- package/dist/vendors/analytics/plausible-analytics.js +2 -81
- package/dist/vendors/analytics/posthog.js +2 -200
- package/dist/vendors/analytics/promptwatch.js +2 -29
- package/dist/vendors/analytics/rudderstack.js +2 -183
- package/dist/vendors/analytics/rybbit-analytics.js +2 -63
- package/dist/vendors/analytics/segment.js +2 -56
- package/dist/vendors/analytics/umami-analytics.js +2 -39
- package/dist/vendors/analytics/vercel-analytics.js +2 -53
- package/dist/vendors/email-and-sms/klaviyo.js +2 -0
- package/dist/vendors/functional/crisp.js +2 -100
- package/dist/vendors/functional/front-chat.js +2 -0
- package/dist/vendors/functional/intercom.js +2 -45
- package/dist/vendors/tag-managers/cloudflare-zaraz.js +2 -98
- package/dist/vendors/tag-managers/google-tag-manager.js +2 -59
- package/dist/vercel-analytics.js +2 -0
- package/dist/x-pixel.js +2 -0
- package/dist-types/adobe-analytics.d.ts +2 -0
- package/dist-types/ahrefs-analytics.d.ts +2 -0
- package/dist-types/amplitude.d.ts +2 -0
- package/dist-types/clearbit.d.ts +2 -0
- package/dist-types/cloudflare-web-analytics.d.ts +2 -0
- package/dist-types/cloudflare-zaraz.d.ts +2 -0
- package/dist-types/crisp.d.ts +2 -0
- package/dist-types/databuddy.d.ts +2 -0
- package/dist-types/e2e-test-utils.d.ts +2 -0
- package/dist-types/engine/compile.d.ts +2 -3
- package/dist-types/engine/runtime.d.ts +2 -3
- package/dist-types/events.d.ts +2 -0
- package/dist-types/fathom-analytics.d.ts +2 -0
- package/dist-types/front-chat.d.ts +2 -0
- package/dist-types/google-tag-manager.d.ts +2 -0
- package/dist-types/google-tag.d.ts +2 -0
- package/dist-types/heap.d.ts +2 -0
- package/dist-types/hightouch.d.ts +2 -0
- package/dist-types/hotjar.d.ts +2 -0
- package/dist-types/intercom.d.ts +2 -0
- package/dist-types/klaviyo.d.ts +2 -0
- package/dist-types/linkedin-insights.d.ts +2 -0
- package/dist-types/logrocket.d.ts +2 -0
- package/dist-types/matomo-analytics.d.ts +2 -0
- package/dist-types/meta-pixel.d.ts +2 -0
- package/dist-types/microsoft-clarity.d.ts +2 -0
- package/dist-types/microsoft-uet.d.ts +2 -0
- package/dist-types/mixpanel-analytics.d.ts +2 -0
- package/dist-types/one-dollar-stats.d.ts +2 -0
- package/dist-types/openai-pixel.d.ts +2 -0
- package/dist-types/pinterest-tag.d.ts +2 -0
- package/dist-types/pirsch.d.ts +2 -0
- package/dist-types/plausible-analytics.d.ts +2 -0
- package/dist-types/posthog.d.ts +2 -0
- package/dist-types/promptwatch.d.ts +2 -0
- package/dist-types/reddit-pixel.d.ts +2 -0
- package/dist-types/registry.d.ts +2 -458
- package/dist-types/resolve.d.ts +2 -9
- package/dist-types/rudderstack.d.ts +2 -0
- package/dist-types/rybbit-analytics.d.ts +2 -0
- package/dist-types/segment.d.ts +2 -0
- package/dist-types/snapchat-pixel.d.ts +2 -0
- package/dist-types/tiktok-pixel.d.ts +2 -0
- package/dist-types/types.d.ts +2 -314
- package/dist-types/umami-analytics.d.ts +2 -0
- package/dist-types/vendors/_shared/attributes.d.ts +2 -35
- package/dist-types/vendors/_shared/google-consent.d.ts +2 -47
- package/dist-types/vendors/_shared/install-builders.d.ts +2 -30
- package/dist-types/vendors/_shared/required-id.d.ts +2 -0
- package/dist-types/vendors/_shared/script-url.d.ts +2 -75
- package/dist-types/vendors/ads-and-pixels/linkedin-insights.d.ts +2 -92
- package/dist-types/vendors/ads-and-pixels/meta-pixel.d.ts +2 -289
- package/dist-types/vendors/ads-and-pixels/microsoft-uet.d.ts +2 -105
- package/dist-types/vendors/ads-and-pixels/openai-pixel.d.ts +2 -211
- package/dist-types/vendors/ads-and-pixels/pinterest-tag.d.ts +2 -0
- package/dist-types/vendors/ads-and-pixels/reddit-pixel.d.ts +2 -210
- package/dist-types/vendors/ads-and-pixels/snapchat-pixel.d.ts +2 -171
- package/dist-types/vendors/ads-and-pixels/tiktok-pixel.d.ts +2 -106
- package/dist-types/vendors/ads-and-pixels/x-pixel.d.ts +2 -183
- package/dist-types/vendors/analytics/adobe-analytics.d.ts +2 -75
- package/dist-types/vendors/analytics/ahrefs-analytics.d.ts +2 -62
- package/dist-types/vendors/analytics/amplitude.d.ts +2 -234
- package/dist-types/vendors/analytics/clearbit.d.ts +2 -60
- package/dist-types/vendors/analytics/cloudflare-web-analytics.d.ts +2 -67
- package/dist-types/vendors/analytics/databuddy.d.ts +2 -147
- package/dist-types/vendors/analytics/fathom-analytics.d.ts +2 -90
- package/dist-types/vendors/analytics/google-tag.d.ts +2 -93
- package/dist-types/vendors/analytics/heap.d.ts +2 -316
- package/dist-types/vendors/analytics/hightouch.d.ts +2 -285
- package/dist-types/vendors/analytics/hotjar.d.ts +2 -73
- package/dist-types/vendors/analytics/logrocket.d.ts +2 -101
- package/dist-types/vendors/analytics/matomo-analytics.d.ts +2 -41
- package/dist-types/vendors/analytics/microsoft-clarity.d.ts +2 -97
- package/dist-types/vendors/analytics/mixpanel-analytics.d.ts +2 -113
- package/dist-types/vendors/analytics/one-dollar-stats.d.ts +2 -0
- package/dist-types/vendors/analytics/pirsch.d.ts +2 -96
- package/dist-types/vendors/analytics/plausible-analytics.d.ts +2 -122
- package/dist-types/vendors/analytics/posthog.d.ts +2 -175
- package/dist-types/vendors/analytics/promptwatch.d.ts +2 -36
- package/dist-types/vendors/analytics/rudderstack.d.ts +2 -330
- package/dist-types/vendors/analytics/rybbit-analytics.d.ts +2 -82
- package/dist-types/vendors/analytics/segment.d.ts +2 -158
- package/dist-types/vendors/analytics/umami-analytics.d.ts +2 -93
- package/dist-types/vendors/analytics/vercel-analytics.d.ts +2 -66
- package/dist-types/vendors/email-and-sms/klaviyo.d.ts +2 -0
- package/dist-types/vendors/functional/crisp.d.ts +2 -78
- package/dist-types/vendors/functional/front-chat.d.ts +2 -0
- package/dist-types/vendors/functional/intercom.d.ts +2 -135
- package/dist-types/vendors/tag-managers/cloudflare-zaraz.d.ts +2 -39
- package/dist-types/vendors/tag-managers/google-tag-manager.d.ts +2 -94
- package/dist-types/vercel-analytics.d.ts +2 -0
- package/dist-types/x-pixel.d.ts +2 -0
- package/docs/README.md +129 -59
- package/docs/assets/v3/bottom-bar.png +0 -0
- package/docs/assets/v3/brand-card.png +0 -0
- package/docs/assets/v3/brand-preferences.png +0 -0
- package/docs/assets/v3/choice-wall.png +0 -0
- package/docs/assets/v3/headless-bar-html.png +0 -0
- package/docs/assets/v3/headless-bar-mobile.png +0 -0
- package/docs/assets/v3/headless-bar.png +0 -0
- package/docs/assets/v3/slim-bar.png +0 -0
- package/docs/concepts/choose-your-setup.md +87 -0
- package/docs/concepts/consent-categories.md +84 -0
- package/docs/concepts/consent-state.md +357 -0
- package/docs/{guides → concepts}/data-fetching.md +31 -27
- package/docs/concepts/how-consent-works.md +123 -0
- package/docs/concepts/policies.md +71 -0
- package/docs/customization/class-names.md +202 -0
- package/docs/customization/dark-mode.md +157 -0
- package/docs/customization/motion.md +119 -0
- package/docs/customization/overview.md +67 -33
- package/docs/customization/recipes.md +839 -47
- package/docs/customization/slots.md +216 -35
- package/docs/customization/stylesheets.md +147 -0
- package/docs/customization/tailwind.md +842 -0
- package/docs/customization/tokens.md +166 -36
- package/docs/customization/translations.md +61 -3
- package/docs/frameworks/astro/embeds.md +160 -0
- package/docs/frameworks/astro/network-blocker.md +86 -0
- package/docs/frameworks/astro/scripts.md +146 -0
- package/docs/frameworks/html/embeds.md +142 -0
- package/docs/frameworks/html/network-blocker.md +105 -0
- package/docs/frameworks/html/scripts.md +164 -0
- package/docs/frameworks/javascript/scripts.md +119 -0
- package/docs/frameworks/next/embeds.md +90 -0
- package/docs/frameworks/next/network-blocker.md +153 -0
- package/docs/frameworks/next/scripts.md +196 -0
- package/docs/frameworks/nuxt/embeds.md +81 -0
- package/docs/frameworks/nuxt/network-blocker.md +97 -0
- package/docs/frameworks/nuxt/scripts.md +89 -0
- package/docs/frameworks/react/embeds.md +89 -0
- package/docs/frameworks/react/network-blocker.md +140 -0
- package/docs/frameworks/react/scripts.md +115 -0
- package/docs/frameworks/svelte/embeds.md +96 -0
- package/docs/frameworks/svelte/network-blocker.md +141 -0
- package/docs/frameworks/svelte/scripts.md +137 -0
- package/docs/frameworks/sveltekit/embeds.md +103 -0
- package/docs/frameworks/sveltekit/network-blocker.md +149 -0
- package/docs/frameworks/sveltekit/scripts.md +141 -0
- package/docs/frameworks/tanstack-start/embeds.md +96 -0
- package/docs/frameworks/tanstack-start/network-blocker.md +145 -0
- package/docs/frameworks/tanstack-start/scripts.md +103 -0
- package/docs/frameworks/vue/embeds.md +84 -0
- package/docs/frameworks/vue/network-blocker.md +99 -0
- package/docs/frameworks/vue/scripts.md +93 -0
- package/docs/guides/banner-experiments.md +654 -0
- package/docs/guides/troubleshooting.md +120 -47
- package/docs/guides/verify-consent.md +81 -49
- package/docs/integrations/adobe-analytics.md +168 -160
- package/docs/integrations/ahrefs-analytics.md +153 -155
- package/docs/integrations/amplitude.md +163 -157
- package/docs/integrations/building-integrations.md +136 -37
- package/docs/integrations/clearbit.md +155 -155
- package/docs/integrations/cloudflare-web-analytics.md +157 -157
- package/docs/integrations/cloudflare-zaraz.md +210 -262
- package/docs/integrations/crisp.md +165 -159
- package/docs/integrations/databuddy.md +158 -174
- package/docs/integrations/fathom-analytics.md +159 -157
- package/docs/integrations/front-chat.md +322 -0
- package/docs/integrations/google-maps.md +119 -84
- package/docs/integrations/google-tag-manager.md +179 -164
- package/docs/integrations/google-tag.md +164 -161
- package/docs/integrations/heap.md +164 -156
- package/docs/integrations/hightouch.md +162 -158
- package/docs/integrations/hotjar.md +160 -156
- package/docs/integrations/intercom.md +184 -154
- package/docs/integrations/klaviyo.md +486 -0
- package/docs/integrations/linkedin-insights.md +175 -151
- package/docs/integrations/logrocket.md +161 -157
- package/docs/integrations/matomo-analytics.md +189 -179
- package/docs/integrations/meta-pixel.md +189 -151
- package/docs/integrations/microsoft-clarity.md +164 -156
- package/docs/integrations/microsoft-uet.md +149 -155
- package/docs/integrations/mixpanel-analytics.md +156 -161
- package/docs/integrations/one-dollar-stats.md +306 -0
- package/docs/integrations/openai-pixel.md +205 -302
- package/docs/integrations/overview.md +143 -83
- package/docs/integrations/pinterest-tag.md +329 -0
- package/docs/integrations/pirsch.md +170 -160
- package/docs/integrations/plausible-analytics.md +173 -159
- package/docs/integrations/posthog.md +227 -242
- package/docs/integrations/promptwatch.md +155 -155
- package/docs/integrations/reddit-pixel.md +186 -158
- package/docs/integrations/rudderstack.md +202 -187
- package/docs/integrations/rybbit-analytics.md +172 -161
- package/docs/integrations/segment.md +183 -155
- package/docs/integrations/snapchat-pixel.md +187 -157
- package/docs/integrations/tiktok-pixel.md +172 -151
- package/docs/integrations/umami-analytics.md +164 -159
- package/docs/integrations/vercel-analytics.md +167 -158
- package/docs/integrations/x-pixel.md +177 -151
- package/docs/integrations/youtube.md +122 -87
- package/docs/upgrade-v3.md +490 -354
- package/package.json +12 -236
- package/dist-types/__tests__/helpers.d.ts +0 -141
- package/docs/assets/v3/brand-bar.png +0 -0
- package/docs/assets/v3/mobile-card.png +0 -0
- package/docs/assets/v3/preferences.png +0 -0
- package/docs/frameworks/javascript/script-loader.md +0 -94
- package/docs/frameworks/next/script-loader.md +0 -210
- package/docs/frameworks/react/script-loader.md +0 -63
- package/docs/guides/consent-state.md +0 -60
- package/docs/guides/deployment-modes.md +0 -75
- package/docs/integrations/clear-on-revocation.md +0 -167
- package/docs/integrations/granular-consent.md +0 -208
|
@@ -1,210 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Load scripts with consent
|
|
3
|
-
description: Register vendor scripts in your existing Next.js ConsentRoot and
|
|
4
|
-
handle loading and revocation.
|
|
5
|
-
group: frameworks
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Keep one owner for vendor scripts
|
|
9
|
-
|
|
10
|
-
The [App Router](https://c15t.com/docs/frameworks/next/app-router) and
|
|
11
|
-
[Pages Router](https://c15t.com/docs/frameworks/next/pages-router) setups already register scripts
|
|
12
|
-
in a client wrapper. Keep that wrapper and add vendors to `lib/scripts.ts`.
|
|
13
|
-
If you are adding scripts to an existing c15t setup, install the helpers and
|
|
14
|
-
use the same registration pattern below.
|
|
15
|
-
|
|
16
|
-
| Package manager | Command |
|
|
17
|
-
| :-------------- | :-------------------------- |
|
|
18
|
-
| npm | `npm install @c15t/scripts` |
|
|
19
|
-
| pnpm | `pnpm add @c15t/scripts` |
|
|
20
|
-
| yarn | `yarn add @c15t/scripts` |
|
|
21
|
-
| bun | `bun add @c15t/scripts` |
|
|
22
|
-
|
|
23
|
-
Keep `c15t.config.ts` and the manifest route from your router setup. These shared
|
|
24
|
-
URLs connect initialization and consent submissions to the same backend.
|
|
25
|
-
|
|
26
|
-
## Register scripts in a client wrapper
|
|
27
|
-
|
|
28
|
-
The [runnable Next.js example](https://c15t.com/docs/examples) uses PostHog for measurement and
|
|
29
|
-
X Pixel for marketing. Set `NEXT_PUBLIC_POSTHOG_KEY` and
|
|
30
|
-
`NEXT_PUBLIC_X_PIXEL_ID` to your own project identifiers before building.
|
|
31
|
-
`NEXT_PUBLIC_POSTHOG_HOST` optionally selects your PostHog region's API host.
|
|
32
|
-
Omit a vendor's ID to leave that integration disabled, or replace its helper
|
|
33
|
-
with the [integration](../../integrations/overview.md) your application uses. Include the
|
|
34
|
-
measurement and marketing categories in your policy for these two vendors.
|
|
35
|
-
|
|
36
|
-
Create `lib/scripts.ts` with the example's script configuration:
|
|
37
|
-
|
|
38
|
-
```ts title="lib/scripts.ts"
|
|
39
|
-
import { posthog } from '@c15t/scripts/posthog';
|
|
40
|
-
import { xPixel } from '@c15t/scripts/x-pixel';
|
|
41
|
-
import type { Script } from 'c15t';
|
|
42
|
-
|
|
43
|
-
export const posthogConfigured = Boolean(process.env.NEXT_PUBLIC_POSTHOG_KEY);
|
|
44
|
-
export const xPixelConfigured = Boolean(process.env.NEXT_PUBLIC_X_PIXEL_ID);
|
|
45
|
-
|
|
46
|
-
export const scripts: Script[] = [];
|
|
47
|
-
|
|
48
|
-
if (process.env.NEXT_PUBLIC_POSTHOG_KEY) {
|
|
49
|
-
scripts.push(
|
|
50
|
-
posthog({
|
|
51
|
-
apiHost: process.env.NEXT_PUBLIC_POSTHOG_HOST,
|
|
52
|
-
id: process.env.NEXT_PUBLIC_POSTHOG_KEY,
|
|
53
|
-
initOptions: { cookieless_mode: 'never' },
|
|
54
|
-
loadMode: 'after-consent',
|
|
55
|
-
})
|
|
56
|
-
);
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
if (process.env.NEXT_PUBLIC_X_PIXEL_ID) {
|
|
60
|
-
scripts.push(xPixel({ pixelId: process.env.NEXT_PUBLIC_X_PIXEL_ID }));
|
|
61
|
-
}
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
PostHog waits for measurement consent here. `cookieless_mode: 'never'` disables
|
|
65
|
-
cookieless capture after rejection. X Pixel waits for marketing consent. Remove
|
|
66
|
-
any existing loader for these vendors, including `next/script` and tag-manager
|
|
67
|
-
entries, so each integration loads once.
|
|
68
|
-
|
|
69
|
-
Create this client wrapper. It keeps scripts and browser callbacks in the client
|
|
70
|
-
while the router supplies the visitor's resolved state through `state`:
|
|
71
|
-
|
|
72
|
-
```tsx title="components/consent.tsx"
|
|
73
|
-
'use client';
|
|
74
|
-
|
|
75
|
-
import type { ReactNode } from 'react';
|
|
76
|
-
import {
|
|
77
|
-
ConsentBanner,
|
|
78
|
-
ConsentDialog,
|
|
79
|
-
ConsentDialogLink,
|
|
80
|
-
ConsentRoot,
|
|
81
|
-
} from 'c15t/next';
|
|
82
|
-
import type { ConsentRootProps } from 'c15t/next';
|
|
83
|
-
import { consentConfig } from '../c15t.config';
|
|
84
|
-
import { scripts } from '../lib/scripts';
|
|
85
|
-
|
|
86
|
-
export function Consent({
|
|
87
|
-
children,
|
|
88
|
-
state,
|
|
89
|
-
}: {
|
|
90
|
-
children: ReactNode;
|
|
91
|
-
state: ConsentRootProps['state'];
|
|
92
|
-
}) {
|
|
93
|
-
return (
|
|
94
|
-
<ConsentRoot state={state} config={consentConfig} scripts={scripts}>
|
|
95
|
-
{children}
|
|
96
|
-
<ConsentBanner />
|
|
97
|
-
<ConsentDialog />
|
|
98
|
-
<footer>
|
|
99
|
-
<ConsentDialogLink>Privacy settings</ConsentDialogLink>
|
|
100
|
-
</footer>
|
|
101
|
-
</ConsentRoot>
|
|
102
|
-
);
|
|
103
|
-
}
|
|
104
|
-
```
|
|
105
|
-
|
|
106
|
-
`ConsentRoot` already provides the consent runtime. Mount this wrapper once;
|
|
107
|
-
do not add a second provider. Keep your site's content and footer inside it.
|
|
108
|
-
|
|
109
|
-
## Pass prepared consent through your router
|
|
110
|
-
|
|
111
|
-
App Router awaits the prefetch in the `ResolvedConsent` Server Component from
|
|
112
|
-
the [App Router guide](https://c15t.com/docs/frameworks/next/app-router) and renders the
|
|
113
|
-
wrapper inside it. This partial example is that component; keep the
|
|
114
|
-
`Suspense` boundary, `html`, `body` and stylesheet from your existing layout:
|
|
115
|
-
|
|
116
|
-
```tsx
|
|
117
|
-
import type { ReactNode } from 'react';
|
|
118
|
-
import { resolveConsent } from 'c15t/next/server';
|
|
119
|
-
import { consentConfig } from '../c15t.config';
|
|
120
|
-
import { Consent } from '../components/consent';
|
|
121
|
-
|
|
122
|
-
async function ResolvedConsent({ children }: { children: ReactNode }) {
|
|
123
|
-
const state = await resolveConsent({ config: consentConfig });
|
|
124
|
-
return <Consent state={state}>{children}</Consent>;
|
|
125
|
-
}
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
To stream the page shell before consent resolves instead, pass the unawaited
|
|
129
|
-
promise from a synchronous layout as described in
|
|
130
|
-
[stream the page while consent resolves](https://c15t.com/docs/frameworks/next/app-router#stream-the-page-while-consent-resolves).
|
|
131
|
-
|
|
132
|
-
Pages Router passes `state={pageProps.consentState ?? {}}` to this wrapper
|
|
133
|
-
in `_app.tsx`. Keep `getServerSideProps` and its `c15t/next/pages` helper.
|
|
134
|
-
The router guides contain complete layout and `_app.tsx` files.
|
|
135
|
-
|
|
136
|
-
For static export or browser-only initialization, pass `state={{}}` and keep
|
|
137
|
-
that setup's existing transport. Register scripts on its existing `ConsentRoot`;
|
|
138
|
-
do not introduce server prefetch or local routes just to add a vendor.
|
|
139
|
-
|
|
140
|
-
## Check each vendor's loading behavior
|
|
141
|
-
|
|
142
|
-
The example explicitly configures PostHog to load after consent and disables
|
|
143
|
-
cookieless capture. Those settings are deliberate; its default helper can load
|
|
144
|
-
before consent and use the SDK's consent controls. Read the
|
|
145
|
-
[PostHog guide](../../integrations/posthog.md) before changing them.
|
|
146
|
-
|
|
147
|
-
Ordinary scripts wait for their category's effective permission. Give each
|
|
148
|
-
script a stable unique `id` and remove any other loader for the same vendor.
|
|
149
|
-
Helpers with `alwaysLoad` may load an SDK before permission is granted; a
|
|
150
|
-
category field alone does not guarantee no requests. See the
|
|
151
|
-
[vendor guides](../../integrations/overview.md) for their exact contracts.
|
|
152
|
-
|
|
153
|
-
Removing a script element cannot undo executed JavaScript or requests already
|
|
154
|
-
sent. PostHog exposes capture controls; X Pixel has no consent-update API.
|
|
155
|
-
Stop future event calls after revocation and test a change from allowed to
|
|
156
|
-
denied, as well as initial denial.
|
|
157
|
-
|
|
158
|
-
## Verify the integration
|
|
159
|
-
|
|
160
|
-
With an opt-in policy and no saved choice, neither configured example vendor
|
|
161
|
-
should load. Allow measurement only: PostHog loads and X Pixel remains blocked.
|
|
162
|
-
Reject, reload, and reopen Privacy settings to confirm the choice persists.
|
|
163
|
-
|
|
164
|
-
Use the [runnable example](https://c15t.com/docs/examples) to inspect the same script definitions
|
|
165
|
-
with DevTools, or follow [verification](../../guides/verify-consent.md) in your app.
|
|
166
|
-
Use [custom integrations](../../integrations/building-integrations.md) for an
|
|
167
|
-
unlisted vendor. Google helpers have a separate
|
|
168
|
-
[Consent Mode contract](../../integrations/google-tag-manager.md).
|
|
169
|
-
|
|
170
|
-
## Granular consent
|
|
171
|
-
|
|
172
|
-
A visitor can grant marketing and still turn one vendor off. Declare the
|
|
173
|
-
vendors next to the scripts in `lib/scripts.ts`, with the `vendor` slug each
|
|
174
|
-
script already carries, and pass both to `ConsentRoot`:
|
|
175
|
-
|
|
176
|
-
```ts title="lib/scripts.ts"
|
|
177
|
-
import type { Vendor } from 'c15t';
|
|
178
|
-
|
|
179
|
-
export const vendors: Vendor[] = [
|
|
180
|
-
{
|
|
181
|
-
id: 'x-pixel',
|
|
182
|
-
name: 'X Pixel',
|
|
183
|
-
category: 'marketing',
|
|
184
|
-
privacyPolicyUrl: 'https://x.com/privacy',
|
|
185
|
-
},
|
|
186
|
-
];
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
```tsx title="components/consent.tsx"
|
|
190
|
-
import { scripts, vendors } from '../lib/scripts';
|
|
191
|
-
|
|
192
|
-
<ConsentRoot state={state} config={consentConfig} scripts={scripts} vendors={vendors}>
|
|
193
|
-
{children}
|
|
194
|
-
</ConsentRoot>
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
The preference center lists each vendor under its category with a switch.
|
|
198
|
-
Integrations from `@c15t/scripts` set `vendor` to their manifest slug, so
|
|
199
|
-
`xPixel()` needs no extra wiring; give a hand-written script the same slug
|
|
200
|
-
in its `vendor` field. A backend manifest can declare vendors too. See
|
|
201
|
-
[granular consent](../../integrations/granular-consent.md) for storage,
|
|
202
|
-
bulk actions and the hooks a custom control uses.
|
|
203
|
-
|
|
204
|
-
## Clear stored tracking data
|
|
205
|
-
|
|
206
|
-
Script gating does not remove cookies or Web Storage entries that a script
|
|
207
|
-
already wrote. Add `clearOnRevocation` to your `ConsentRoot` or provider
|
|
208
|
-
options to remove declared data when its category is denied. See
|
|
209
|
-
[clear on revocation](../../integrations/clear-on-revocation.md) for configuration
|
|
210
|
-
and browser limits.
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Load scripts with consent
|
|
3
|
-
description: Register vendor scripts once and let effective permissions control loading.
|
|
4
|
-
group: frameworks
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Register scripts on the provider
|
|
8
|
-
|
|
9
|
-
Install `@c15t/scripts` for vendor helpers. This React-compatible client component
|
|
10
|
-
uses Inth as the backend. Set the URL to the endpoint supplied by your Inth
|
|
11
|
-
project and keep the component mounted around your application.
|
|
12
|
-
|
|
13
|
-
```tsx title="components/consent.tsx"
|
|
14
|
-
'use client';
|
|
15
|
-
|
|
16
|
-
import type { ReactNode } from 'react';
|
|
17
|
-
import { ConsentProvider, ConsentBanner, ConsentDialog, ConsentDialogLink, hosted } from 'c15t/react';
|
|
18
|
-
import { metaPixel } from '@c15t/scripts/meta-pixel';
|
|
19
|
-
|
|
20
|
-
const mode = hosted({ url: 'https://your-project.inth.app' });
|
|
21
|
-
const scripts = [metaPixel({ pixelId: '123456789012345' })];
|
|
22
|
-
|
|
23
|
-
export function Consent({ children }: { children: ReactNode }) {
|
|
24
|
-
return (
|
|
25
|
-
<ConsentProvider options={{ mode, scripts }}>
|
|
26
|
-
{children}
|
|
27
|
-
<ConsentBanner />
|
|
28
|
-
<ConsentDialog />
|
|
29
|
-
<ConsentDialogLink>Privacy settings</ConsentDialogLink>
|
|
30
|
-
</ConsentProvider>
|
|
31
|
-
);
|
|
32
|
-
}
|
|
33
|
-
```
|
|
34
|
-
|
|
35
|
-
Import your adapter's stylesheet globally, as in the framework quickstart. For
|
|
36
|
-
an existing server-resolved `ConsentRoot`, keep that root and pass
|
|
37
|
-
`scripts` as a top-level prop instead of mounting a second provider.
|
|
38
|
-
|
|
39
|
-
## Understand loading and revocation
|
|
40
|
-
|
|
41
|
-
Ordinary scripts wait for their category's effective permission. Give each
|
|
42
|
-
script a stable unique `id` and remove any other loader for the same vendor.
|
|
43
|
-
Some helpers use `alwaysLoad` to load the SDK and signal consent through its own
|
|
44
|
-
API. Read the vendor guide; a category field alone does not guarantee no
|
|
45
|
-
requests.
|
|
46
|
-
|
|
47
|
-
Removing a script element cannot undo JavaScript that already executed or
|
|
48
|
-
requests already sent. Use the vendor's supported consent and cleanup behavior,
|
|
49
|
-
and stop future event calls after revocation. Test both initial denial and a
|
|
50
|
-
change from allowed to denied.
|
|
51
|
-
|
|
52
|
-
Use [custom integrations](../../integrations/building-integrations.md) for an
|
|
53
|
-
unlisted vendor and [verification](../../guides/verify-consent.md) for the network
|
|
54
|
-
checks. Google helpers have a separate
|
|
55
|
-
[Consent Mode contract](../../integrations/google-tag-manager.md).
|
|
56
|
-
|
|
57
|
-
## Clear stored tracking data
|
|
58
|
-
|
|
59
|
-
Script gating does not remove cookies or Web Storage entries that a script
|
|
60
|
-
already wrote. Add `clearOnRevocation` to `ConsentProvider.options` to remove
|
|
61
|
-
declared data when its category is denied. See
|
|
62
|
-
[clear on revocation](../../integrations/clear-on-revocation.md) for configuration
|
|
63
|
-
and browser limits.
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Understand consent state
|
|
3
|
-
description: Distinguish policy resolution, effective permissions, explicit
|
|
4
|
-
choices, notices and privacy signals.
|
|
5
|
-
group: guides
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Use effective permissions to gate features
|
|
9
|
-
|
|
10
|
-
`effectivePermissions` answers whether a category is allowed now. It combines
|
|
11
|
-
the resolved policy, stored choices and privacy signals. Under an opt-out rule,
|
|
12
|
-
permission can be true before the visitor acts. It is not evidence of a recorded
|
|
13
|
-
grant.
|
|
14
|
-
|
|
15
|
-
| Task | State or API |
|
|
16
|
-
| ------------------------------------------- | ---------------------------------------------------- |
|
|
17
|
-
| Load a script or render an optional feature | `effectivePermissions`, React `useConsent(category)` |
|
|
18
|
-
| Inspect what the visitor confirmed | `explicitChoice` |
|
|
19
|
-
| Decide whether to show a prompt | `promptRequirement` |
|
|
20
|
-
| Explain regional behavior | `policyRule` |
|
|
21
|
-
| Diagnose initialization | `resolution` |
|
|
22
|
-
|
|
23
|
-
## Record only explicit visitor actions
|
|
24
|
-
|
|
25
|
-
```ts
|
|
26
|
-
// Run in the corresponding click or form-submit handler.
|
|
27
|
-
await kernel.commands.save('all');
|
|
28
|
-
await kernel.commands.save('none');
|
|
29
|
-
await kernel.commands.save({ marketing: false });
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
These are three separate examples: accept, reject and a partial save. A partial
|
|
33
|
-
save confirms only the supplied categories and keeps the other categories'
|
|
34
|
-
confirmation times. Do not call all three in one handler.
|
|
35
|
-
|
|
36
|
-
`onChoiceRecorded` reports an explicit choice. `onPermissionsChanged` reports
|
|
37
|
-
changes in effective permissions, including changes caused by expiry or privacy
|
|
38
|
-
signals. Hydration must not be counted as another visitor choice.
|
|
39
|
-
|
|
40
|
-
## Treat notices and privacy signals separately
|
|
41
|
-
|
|
42
|
-
`commands.dismissNotice()` acknowledges the current notice. It does not grant
|
|
43
|
-
categories or overwrite existing denials. Global Privacy Control, or GPC, is a
|
|
44
|
-
browser privacy signal. Its configured restrictions can change permissions
|
|
45
|
-
without creating an explicit choice.
|
|
46
|
-
|
|
47
|
-
A rule with `prompt: 'none'` can still require a persistent preferences entry
|
|
48
|
-
point. Check the policy's rights instead of hiding preferences merely because
|
|
49
|
-
the banner is absent. An unresolved rule is another distinct state; optional
|
|
50
|
-
permissions stay denied until resolution succeeds.
|
|
51
|
-
|
|
52
|
-
## Preserve records during hydration
|
|
53
|
-
|
|
54
|
-
Server helpers return records with policy information and evaluation time.
|
|
55
|
-
Forward that configuration intact. Copying an allowed category into a receipt
|
|
56
|
-
would invent a grant and lose its original confirmation time.
|
|
57
|
-
|
|
58
|
-
Valid v2 records can be read without a startup rewrite. The next explicit action
|
|
59
|
-
writes the v3 format. See [migration](../upgrade-v3.md) for expiry, partial saves,
|
|
60
|
-
custom transports and backend contract changes.
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Choose a deployment mode
|
|
3
|
-
description: Choose who runs your consent backend, then select manifest, init or
|
|
4
|
-
offline resolution for your deployment.
|
|
5
|
-
group: guides
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Use Inth for managed policy and records
|
|
9
|
-
|
|
10
|
-
Start with [Inth](https://inth.com) unless you need to operate the consent
|
|
11
|
-
service yourself or deliberately need only local browser records. Configure
|
|
12
|
-
policy rules and trusted origins in the project, then use its exact backend
|
|
13
|
-
endpoint in your framework setup.
|
|
14
|
-
|
|
15
|
-
| Backend ownership | Policy source | Record storage | Use when |
|
|
16
|
-
| ------------------------- | ------------------------------------------------------ | ---------------------------------------- | ------------------------------------------------------------------------- |
|
|
17
|
-
| Inth hosted service | Centrally managed policy through a manifest or `/init` | Browser records plus backend submissions | You want managed policy and consent records |
|
|
18
|
-
| Self-hosted c15t | Your backend's manifest or `/init` | Browser records plus your database | You need to operate the service and its infrastructure |
|
|
19
|
-
| Browser-only offline mode | Bundled `policyRules` | Browser persistence | Local development and tests. Not recommended for production environments. |
|
|
20
|
-
|
|
21
|
-
Hosted and self-hosted c15t use the same transport protocol. Switching who runs
|
|
22
|
-
the backend does not require switching from manifests to `/init`.
|
|
23
|
-
|
|
24
|
-
## Choose data fetching separately
|
|
25
|
-
|
|
26
|
-
For Next.js deployments with a runtime server, use the
|
|
27
|
-
[manifest setup](https://c15t.com/docs/frameworks/next/data-fetching). It reuses public policy data
|
|
28
|
-
in your application while consent writes still go to Inth. Regular backend
|
|
29
|
-
`/init` is available when you want backend-owned request resolution or a simpler
|
|
30
|
-
browser setup. See [data fetching and transports](./data-fetching.md) for
|
|
31
|
-
the comparison, including custom transports and offline mode.
|
|
32
|
-
|
|
33
|
-
Manifest resolution removes the per-visitor `/init` request, and with it the
|
|
34
|
-
backend's only count of visitors. The server adapters replace it with a session
|
|
35
|
-
report: after each resolution, on a server-rendered page or the same-origin
|
|
36
|
-
init route, the host posts a small report to the backend's `POST /sessions`,
|
|
37
|
-
server-to-server and detached from the response. The browser makes no request
|
|
38
|
-
and the report stores no identity; the visitor's IP and user agent travel as
|
|
39
|
-
forwarded headers under the backend's usual IP handling. Each report is one
|
|
40
|
-
resolution; a page view can produce a `render` and a `route` report, and the
|
|
41
|
-
consuming side groups them into sessions by address and user agent within a
|
|
42
|
-
window. Static output resolves in the browser and sends none. Set `reportSessions: false` on an adapter to turn
|
|
43
|
-
it off.
|
|
44
|
-
|
|
45
|
-
## Match initialization to your application output
|
|
46
|
-
|
|
47
|
-
| Application output | Initial state | Required setup |
|
|
48
|
-
| ------------------ | ------------------------- | ----------------------------------------------------------- |
|
|
49
|
-
| Request SSR | Prepared for this visitor | Adapter request helper and matching client configuration |
|
|
50
|
-
| Static HTML or SPA | Resolved in the browser | Reachable external URLs or deliberately bundled local rules |
|
|
51
|
-
|
|
52
|
-
Request SSR can include the visitor's prompt in the initial HTML. Pass the
|
|
53
|
-
prepared records and policy resolution through to hydration. Do not convert
|
|
54
|
-
effective permissions into new stored choices.
|
|
55
|
-
|
|
56
|
-
Static HTML is shared across visitors. It cannot contain a choice resolved from
|
|
57
|
-
each visitor's cookies or geography at build time. A static site can still use
|
|
58
|
-
Inth through browser requests. A same-origin `/api/c15t` URL only works if a
|
|
59
|
-
service actually serves it; a Next.js static export does not run API routes.
|
|
60
|
-
|
|
61
|
-
A manifest contains reusable public policy data. A resolved init response and
|
|
62
|
-
personalized consent HTML belong to a request. Do not give them the same shared
|
|
63
|
-
cache treatment.
|
|
64
|
-
|
|
65
|
-
## Handle initialization and storage failures
|
|
66
|
-
|
|
67
|
-
While no policy resolves, optional permissions stay denied and the stock
|
|
68
|
-
consent UI stays hidden. No banner can mean pending or failed initialization.
|
|
69
|
-
It does not mean permission to load analytics. Observe errors before changing
|
|
70
|
-
presentation, and do not silently switch to offline policy after a hosted
|
|
71
|
-
request fails.
|
|
72
|
-
|
|
73
|
-
Browser storage can also be unavailable. A working in-memory interaction does
|
|
74
|
-
not prove the choice survives reload. Use
|
|
75
|
-
[verification](./verify-consent.md) to test the actual deployment.
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: Clear on revocation
|
|
3
|
-
description: Remove configured first-party cookies and Web Storage keys when
|
|
4
|
-
their consent category is denied.
|
|
5
|
-
group: integrations
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
## Configure cleanup
|
|
9
|
-
|
|
10
|
-
Add `clearOnRevocation` to your provider or runtime options. Declare only the
|
|
11
|
-
data owned by each optional category:
|
|
12
|
-
|
|
13
|
-
```ts
|
|
14
|
-
import { hosted, type ClearOnRevocationConfig } from 'c15t';
|
|
15
|
-
import { createConsentRuntime } from 'c15t/runtime';
|
|
16
|
-
|
|
17
|
-
const clearOnRevocation = {
|
|
18
|
-
measurement: {
|
|
19
|
-
cookies: ['_ga', '_ga_*'],
|
|
20
|
-
localStorage: ['analytics:*'],
|
|
21
|
-
},
|
|
22
|
-
marketing: {
|
|
23
|
-
cookies: ['_fbp'],
|
|
24
|
-
sessionStorage: ['campaign-id'],
|
|
25
|
-
},
|
|
26
|
-
} satisfies ClearOnRevocationConfig;
|
|
27
|
-
|
|
28
|
-
const runtime = createConsentRuntime({
|
|
29
|
-
mode: hosted({ url: '/api/c15t' }),
|
|
30
|
-
clearOnRevocation,
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
// Start in the browser after mount. The endpoint must serve your c15t backend.
|
|
34
|
-
runtime.start();
|
|
35
|
-
|
|
36
|
-
// Call runtime.dispose() when the app no longer needs consent management.
|
|
37
|
-
```
|
|
38
|
-
|
|
39
|
-
For React, pass the same configuration through `ConsentProvider.options`:
|
|
40
|
-
|
|
41
|
-
```tsx
|
|
42
|
-
import type { ReactNode } from 'react';
|
|
43
|
-
import { ConsentProvider, hosted } from 'c15t/react';
|
|
44
|
-
|
|
45
|
-
const mode = hosted({ url: '/api/c15t' });
|
|
46
|
-
|
|
47
|
-
export function Consent({ children }: { children: ReactNode }) {
|
|
48
|
-
return (
|
|
49
|
-
<ConsentProvider
|
|
50
|
-
options={{
|
|
51
|
-
mode,
|
|
52
|
-
clearOnRevocation: {
|
|
53
|
-
measurement: { cookies: ['_ga', '_ga_*'] },
|
|
54
|
-
},
|
|
55
|
-
}}
|
|
56
|
-
>
|
|
57
|
-
{children}
|
|
58
|
-
</ConsentProvider>
|
|
59
|
-
);
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
The same option is available in Next.js and TanStack Start `ConsentRoot` props, Vue and
|
|
64
|
-
Nuxt configuration, Svelte providers, and Astro integration options. Solid and
|
|
65
|
-
other headless integrations can use `createConsentRuntime` as shown above.
|
|
66
|
-
Every adapter uses the same cleanup module.
|
|
67
|
-
|
|
68
|
-
Omitting `clearOnRevocation` leaves cleanup disabled. The provider option is
|
|
69
|
-
initial-only. Remount the provider to replace its cleanup configuration. For
|
|
70
|
-
a shared runtime, configure the runtime owner rather than a borrowing provider.
|
|
71
|
-
|
|
72
|
-
## Matching names and cookie scopes
|
|
73
|
-
|
|
74
|
-
Use an exact string or a nonempty prefix followed by `*`. `_ga_*` matches
|
|
75
|
-
`_ga_ABC123`; it does not match `_ga`. Regular expressions, wildcards in other
|
|
76
|
-
positions, and a bare `*` are unsupported. Web Storage keys may contain spaces,
|
|
77
|
-
Unicode, and punctuation. Cookie names use their raw spelling, without URL
|
|
78
|
-
decoding.
|
|
79
|
-
|
|
80
|
-
Cookies can share a name while having different domains or paths. Cleanup
|
|
81
|
-
tries the current host and its parent domains, and the current path and its
|
|
82
|
-
ancestors. To target a specific scope, use an object:
|
|
83
|
-
|
|
84
|
-
```ts
|
|
85
|
-
const clearOnRevocation = {
|
|
86
|
-
measurement: {
|
|
87
|
-
cookies: [
|
|
88
|
-
{ name: 'analytics-id', domain: 'example.com', path: '/' },
|
|
89
|
-
{ name: 'checkout-metrics', domain: '', path: '/checkout' },
|
|
90
|
-
{ name: 'partitioned-metrics', partitioned: true },
|
|
91
|
-
],
|
|
92
|
-
},
|
|
93
|
-
};
|
|
94
|
-
```
|
|
95
|
-
|
|
96
|
-
An empty `domain` means host-only. Explicit domains and paths replace the
|
|
97
|
-
automatic attempts for that field. Exact names can be deleted at a configured
|
|
98
|
-
path even when the current page cannot read that cookie. Prefix matching can
|
|
99
|
-
only discover cookie names visible to the current page, so use an exact name
|
|
100
|
-
for a cookie on another path.
|
|
101
|
-
|
|
102
|
-
Partitioned cookies require `partitioned: true`; ordinary targets remove
|
|
103
|
-
unpartitioned cookies. Cookie deletion preserves the browser's `__Secure-`
|
|
104
|
-
and `__Host-` prefix requirements. c15t protects its own consent, notice,
|
|
105
|
-
privacy, pending-save, and IAB consent records in cookies and localStorage,
|
|
106
|
-
including configured custom storage keys, even if your patterns match them.
|
|
107
|
-
c15t does not store consent in sessionStorage, so targeted entries there are
|
|
108
|
-
removed even when their names match consent storage keys.
|
|
109
|
-
|
|
110
|
-
## When cleanup runs
|
|
111
|
-
|
|
112
|
-
The runtime attaches cleanup after persistence and the script loader. Cleanup
|
|
113
|
-
waits while the policy is pending. On the first settled snapshot, it removes
|
|
114
|
-
configured data for every denied category. This includes a new opt-in visitor
|
|
115
|
-
who has not made a choice and a returning visitor whose permission expired.
|
|
116
|
-
|
|
117
|
-
After that first pass, cleanup runs when a category changes from allowed to
|
|
118
|
-
denied. Saving a refusal, expiry, a policy change, Global Privacy Control,
|
|
119
|
-
or synchronized records can cause that transition. Under an opt-out policy,
|
|
120
|
-
an expired grant that remains effectively allowed does not trigger deletion.
|
|
121
|
-
The `necessary` category cannot be configured for cleanup.
|
|
122
|
-
|
|
123
|
-
Cleanup keeps waiting if a failed initial request leaves the policy pending.
|
|
124
|
-
If a previously settled policy falls back to denial after an initialization
|
|
125
|
-
failure, cleanup removes its configured data. A later successful retry cannot
|
|
126
|
-
restore deleted data.
|
|
127
|
-
|
|
128
|
-
Runtime construction, server rendering, draft checkbox edits, opening the
|
|
129
|
-
dialog, and disposal do not clear data. Cleanup does not poll storage or repeat
|
|
130
|
-
on unrelated UI updates.
|
|
131
|
-
|
|
132
|
-
## Use an existing kernel
|
|
133
|
-
|
|
134
|
-
For a manually assembled integration, attach the module in the browser after
|
|
135
|
-
persistence hydration and script-loader setup:
|
|
136
|
-
|
|
137
|
-
```ts
|
|
138
|
-
import { createClearOnRevocation } from 'c15t/modules/clear-on-revocation';
|
|
139
|
-
|
|
140
|
-
const cleanup = createClearOnRevocation({
|
|
141
|
-
kernel,
|
|
142
|
-
config: { measurement: { cookies: ['_ga', '_ga_*'] } },
|
|
143
|
-
storageConfig,
|
|
144
|
-
});
|
|
145
|
-
|
|
146
|
-
// Stop observing consent when this integration is torn down.
|
|
147
|
-
cleanup.dispose();
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
Here `kernel` is your existing consent kernel. Pass the same `storageConfig`
|
|
151
|
-
used by persistence so cleanup protects custom record keys. Attaching the
|
|
152
|
-
module can immediately clear denied categories if the policy is already
|
|
153
|
-
settled. Do not also attach it when your provider or runtime owns cleanup.
|
|
154
|
-
|
|
155
|
-
## Browser limits
|
|
156
|
-
|
|
157
|
-
Cleanup can remove JavaScript-accessible first-party cookies and keys in the
|
|
158
|
-
current origin's `localStorage` and `sessionStorage`. It cannot remove
|
|
159
|
-
`HttpOnly` cookies or another origin's data. Keep `HttpOnly` protections and
|
|
160
|
-
use your server to expire cookies that require server access. Cookie deletion
|
|
161
|
-
must match the cookie's scope. See the
|
|
162
|
-
[browser cookie documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Cookies).
|
|
163
|
-
|
|
164
|
-
Browser restrictions can prevent reads or deletions. Cleanup failures do not
|
|
165
|
-
block consent updates. A running SDK may write data again after a sweep, so
|
|
166
|
-
keep script gating and the integration's consent-change or teardown behavior
|
|
167
|
-
configured. Deleting a script element cannot undo JavaScript it already ran.
|