@c15t/react 3.0.0-alpha.9 → 3.0.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 +7 -9
- package/README.md +41 -70
- package/SKILL.md +1 -1
- package/dist/aggregate-components.js +1 -1
- package/dist/components/consent-gate/atoms.js +1 -1
- package/dist/components/consent-gate/frame.js +2 -0
- package/dist/components/consent-gate/index.js +1 -1
- package/dist/components/iab-panel/atoms/root.js +1 -1
- package/dist/components/iab-panel/iab-panel.js +1 -1
- package/dist/components/iab-prompt/atoms/root.js +1 -1
- package/dist/components/iab-prompt/iab-prompt.js +1 -1
- package/dist/components/panel/atoms/root.js +1 -1
- package/dist/components/panel-trigger/atoms/root.js +1 -1
- package/dist/components/panel-trigger/panel-trigger.js +1 -1
- package/dist/components/panel-trigger/toolbar-loader.js +2 -0
- package/dist/components/preferences/atoms/root.js +1 -1
- package/dist/components/prompt/atoms/early-tap-script.js +2 -0
- package/dist/components/prompt/atoms/root.js +1 -1
- package/dist/components/shared/primitives/button.js +1 -1
- package/dist/components/shared/surface-styles.js +1 -1
- package/dist/consent-gate.js +1 -1
- package/dist/context/index.js +1 -1
- package/dist/devtools.js +1 -1
- package/dist/iab/styles.tw3.css +2 -2
- package/dist/iab-dialog-deferred.js +2 -0
- package/dist/iab.js +1 -1
- package/dist/index-parts/consent-gate.js +1 -1
- package/dist/index-parts/core.js +1 -1
- package/dist/index-parts/frame.js +1 -0
- package/dist/index-parts/hosted.js +1 -0
- package/dist/index-parts/offline.js +1 -0
- package/dist/index-parts/presets.js +1 -0
- package/dist/index.js +1 -1
- package/dist/modes.js +1 -0
- package/dist/panel-link.js +1 -1
- package/dist/panel-trigger.js +1 -1
- package/dist/provider.js +1 -1
- package/dist/styles.tw3.css +2 -2
- package/dist/transports/hosted.js +1 -0
- package/dist/transports/manifest.js +1 -0
- package/dist/utils/deferred-module.js +1 -1
- package/dist/version.js +1 -1
- package/dist-types/chunk-warming.d.ts +7 -6
- package/dist-types/components/consent-gate/frame.d.ts +19 -0
- package/dist-types/components/consent-gate/index.d.ts +3 -19
- package/dist-types/components/iab-prompt/iab-prompt.d.ts +1 -1
- package/dist-types/components/panel/index.d.ts +1 -1
- package/dist-types/components/panel-trigger/toolbar-loader.d.ts +34 -0
- package/dist-types/components/preferences/index.d.ts +1 -1
- package/dist-types/components/prompt/atoms/early-tap-script.d.ts +17 -0
- package/dist-types/components/prompt/index.d.ts +1 -1
- package/dist-types/components/shared/surface-styles.d.ts +26 -2
- package/dist-types/consent-gate.d.ts +1 -1
- package/dist-types/context/index.d.ts +3 -3
- package/dist-types/context.d.ts +2 -0
- package/dist-types/gpp.d.ts +1 -1
- package/dist-types/iab-dialog-deferred.d.ts +36 -0
- package/dist-types/iab.d.ts +3 -2
- package/dist-types/index-parts/consent-gate.d.ts +1 -1
- package/dist-types/index-parts/core.d.ts +1 -2
- package/dist-types/index-parts/frame.d.ts +7 -0
- package/dist-types/index-parts/hosted.d.ts +7 -0
- package/dist-types/index-parts/offline.d.ts +7 -0
- package/dist-types/index-parts/presets.d.ts +7 -0
- package/dist-types/index.d.ts +5 -1
- package/dist-types/modes.d.ts +26 -0
- package/dist-types/panel-link.d.ts +1 -1
- package/dist-types/panel-trigger.d.ts +1 -1
- package/dist-types/provider.d.ts +3 -3
- package/dist-types/transports/hosted.d.ts +36 -0
- package/dist-types/transports/manifest.d.ts +48 -0
- package/dist-types/version.d.ts +1 -1
- package/docs/README.md +7 -9
- package/docs/concepts/choose-your-setup.md +45 -10
- package/docs/concepts/consent-categories.md +1 -1
- package/docs/concepts/consent-state.md +5 -2
- package/docs/concepts/data-fetching.md +100 -42
- package/docs/concepts/modes.md +281 -0
- package/docs/customization/dark-mode.md +1 -1
- package/docs/customization/motion.md +2 -2
- package/docs/customization/recipes.md +4 -4
- package/docs/customization/slots.md +25 -25
- package/docs/customization/stylesheets.md +12 -14
- package/docs/customization/tailwind.md +17 -11
- package/docs/customization/tokens.md +36 -7
- package/docs/frameworks/react/components/consent-banner.md +14 -10
- package/docs/frameworks/react/components/consent-dialog.md +14 -10
- package/docs/frameworks/react/components/consent-provider.md +51 -44
- package/docs/frameworks/react/components.md +14 -10
- package/docs/frameworks/react/content-security-policy.md +21 -12
- package/docs/frameworks/react/hooks.md +2 -2
- package/docs/frameworks/react/iab.md +20 -2
- package/docs/frameworks/react/quickstart.md +63 -97
- package/docs/frameworks/react/rendering.md +168 -94
- package/docs/frameworks/react/scripts.md +19 -28
- package/docs/frameworks/react/troubleshooting.md +57 -25
- package/docs/frameworks/react/upgrade-v3.md +110 -62
- package/docs/guides/banner-experiments.md +21 -6
- package/docs/guides/troubleshooting.md +89 -25
- package/docs/guides/verify-consent.md +23 -8
- package/docs/integrations/adobe-analytics.md +60 -64
- package/docs/integrations/ahrefs-analytics.md +58 -63
- package/docs/integrations/amplitude.md +60 -64
- package/docs/integrations/clearbit.md +59 -63
- package/docs/integrations/cloudflare-web-analytics.md +56 -60
- package/docs/integrations/cloudflare-zaraz.md +55 -57
- package/docs/integrations/crisp.md +64 -69
- package/docs/integrations/databuddy.md +62 -64
- package/docs/integrations/fathom-analytics.md +56 -60
- package/docs/integrations/front-chat.md +56 -60
- package/docs/integrations/google-maps.md +25 -13
- package/docs/integrations/google-tag-manager.md +153 -77
- package/docs/integrations/google-tag.md +134 -78
- package/docs/integrations/heap.md +56 -60
- package/docs/integrations/hightouch.md +55 -60
- package/docs/integrations/hotjar.md +60 -64
- package/docs/integrations/intercom.md +55 -60
- package/docs/integrations/klaviyo.md +65 -66
- package/docs/integrations/linkedin-insights.md +58 -63
- package/docs/integrations/logrocket.md +55 -60
- package/docs/integrations/matomo-analytics.md +58 -60
- package/docs/integrations/meta-pixel.md +56 -60
- package/docs/integrations/microsoft-clarity.md +57 -60
- package/docs/integrations/microsoft-uet.md +58 -61
- package/docs/integrations/mixpanel-analytics.md +73 -75
- package/docs/integrations/one-dollar-stats.md +53 -59
- package/docs/integrations/openai-pixel.md +58 -60
- package/docs/integrations/overview.md +59 -42
- package/docs/integrations/pinterest-tag.md +56 -60
- package/docs/integrations/pirsch.md +54 -60
- package/docs/integrations/plausible-analytics.md +55 -60
- package/docs/integrations/posthog.md +56 -60
- package/docs/integrations/promptwatch.md +57 -63
- package/docs/integrations/reddit-pixel.md +57 -60
- package/docs/integrations/rudderstack.md +65 -67
- package/docs/integrations/rybbit-analytics.md +70 -75
- package/docs/integrations/segment.md +56 -60
- package/docs/integrations/sentry.md +65 -60
- package/docs/integrations/snapchat-pixel.md +54 -60
- package/docs/integrations/tiktok-pixel.md +59 -63
- package/docs/integrations/umami-analytics.md +54 -60
- package/docs/integrations/vercel-analytics.md +53 -59
- package/docs/integrations/vercel-speed-insights.md +317 -0
- package/docs/integrations/x-pixel.md +57 -63
- package/docs/integrations/youtube.md +25 -13
- package/package.json +18 -8
- package/docs/upgrade-v3.md +0 -429
|
@@ -5,34 +5,12 @@ description: Fix a missing banner, early vendor requests, unstyled components
|
|
|
5
5
|
group: frameworks
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
## Why does the build fail to download the manifest?
|
|
9
|
-
|
|
10
|
-
**Check.** `vite build` or `vite dev` stops before compiling, with an error
|
|
11
|
-
from `consentManifest` that starts with `@c15t/core/build:`.
|
|
12
|
-
|
|
13
|
-
| Error | Cause | Fix |
|
|
14
|
-
| -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------ |
|
|
15
|
-
| `build-time manifests require an absolute upstream URL.` | `backendURL` is empty or relative, such as `/api/c15t` | Pass the absolute backend URL from your Inth project |
|
|
16
|
-
| `build-time manifests require an http(s) upstream URL.` | `backendURL` uses another protocol | Use the `https://` URL Inth shows |
|
|
17
|
-
| `/manifest responded 404` | The URL is not your project's backend, such as the `https://your-project.inth.app` placeholder or a URL missing its path prefix | Copy the backend URL exactly as Inth shows it, or set `VITE_C15T_BACKEND_URL` |
|
|
18
|
-
| `/manifest returned an invalid consent manifest.` | The URL answered with something other than a consent manifest, such as an HTML page | Point `backendURL` at the backend itself, not your site or a dashboard page |
|
|
19
|
-
| `fetch failed` | The build cannot reach the backend | Build where the backend is reachable. A failed download never reuses an old snapshot |
|
|
20
|
-
|
|
21
|
-
## Why can't TypeScript find ./c15t-manifest?
|
|
22
|
-
|
|
23
|
-
**Check.** `tsc`, `vue-tsc` or your editor reports that it cannot find the
|
|
24
|
-
module `./c15t-manifest`, on a fresh checkout or in CI.
|
|
25
|
-
|
|
26
|
-
**Fix.** `consentManifest` writes `src/c15t-manifest.ts` when `vite build` or
|
|
27
|
-
`vite dev` starts, and the file is not in Git. Run one of them before the type
|
|
28
|
-
check. In CI, run the build first, or cache the generated file with the build
|
|
29
|
-
output.
|
|
30
|
-
|
|
31
8
|
## There is no banner
|
|
32
9
|
|
|
33
10
|
**Check.** In DevTools Network, find the `GET` request to `/init` on your
|
|
34
|
-
backend URL. With the
|
|
35
|
-
|
|
11
|
+
backend URL. With `hosted()`, the browser sends it while the provider first
|
|
12
|
+
renders. With a bundled `manifest()`, the browser makes no request before the
|
|
13
|
+
banner unless the policy depends on a country or region it does not know.
|
|
36
14
|
|
|
37
15
|
| What you see | Cause | Fix |
|
|
38
16
|
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
@@ -44,6 +22,60 @@ A policy with `prompt: 'none'` shows no banner by design, and so does a
|
|
|
44
22
|
returning visitor with a valid stored choice. [Policies](../../concepts/policies.md)
|
|
45
23
|
explains why a region may not show one.
|
|
46
24
|
|
|
25
|
+
## Why does the build fail to download the manifest?
|
|
26
|
+
|
|
27
|
+
**Check.** `vite build` stops with an error from `consentManifest` that
|
|
28
|
+
starts with the plugin's name, such as
|
|
29
|
+
`@c15t/core/build: could not fetch the consent manifest from <url> during the
|
|
30
|
+
build`. The name is `@c15t/core/build` for `c15t/build` and `@c15t/vue/vite`
|
|
31
|
+
for `c15t/vue/vite`. `vite dev` logs the same message as a warning and keeps
|
|
32
|
+
going. The part in parentheses names the cause:
|
|
33
|
+
|
|
34
|
+
| Message | Cause | Fix |
|
|
35
|
+
| ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
36
|
+
| `fetch failed`, with `ENOTFOUND`, `ECONNREFUSED` or another network error | The build cannot reach the backend | Build where the backend is reachable |
|
|
37
|
+
| `no response within 10 seconds` | The backend did not answer in time | Check the backend, or build where it is reachable |
|
|
38
|
+
| `/manifest responded 404` | The URL is not your project's backend, such as the `https://your-project.inth.app` placeholder or a URL missing its path prefix | Copy the backend URL exactly as Inth shows it, or set `VITE_C15T_BACKEND_URL` |
|
|
39
|
+
| `/manifest returned an invalid consent manifest.` | The URL answered with something other than a consent manifest, such as an HTML page | Point `backendURL` at the backend itself, not your site or a dashboard page |
|
|
40
|
+
|
|
41
|
+
A failed download never reuses an old snapshot. To deploy while the backend
|
|
42
|
+
is down, run the build with `C15T_ON_BUILD_ERROR=runtime`. `snapshot` is then
|
|
43
|
+
`undefined`, and the browser fetches the policy from the backend at runtime.
|
|
44
|
+
|
|
45
|
+
Only a build that uses `manifest()` downloads the manifest. The plugin
|
|
46
|
+
fetches after Vite has dropped the code the app does not use, so a `hosted()`
|
|
47
|
+
or `offline()` build never contacts the backend and never fails this way.
|
|
48
|
+
|
|
49
|
+
An error or warning that says `no backend URL is set` means the plugin found
|
|
50
|
+
no `backendURL` option and no variable. Set `VITE_C15T_BACKEND_URL` (or
|
|
51
|
+
`VITE_INTH_PROJECT_URL`) in `.env` or the build environment, or pass the absolute backend URL from your Inth
|
|
52
|
+
project. The [troubleshooting guide](../../guides/troubleshooting.md#why-does-the-build-fail-to-download-the-manifest)
|
|
53
|
+
lists every message.
|
|
54
|
+
|
|
55
|
+
A notice that the build `skipped the consent manifest fetch` means the backend
|
|
56
|
+
URL is relative, such as `/api/c15t`. Pass the absolute backend URL instead.
|
|
57
|
+
With `onBuildError: 'fail'`, this stops the build with `build-time manifests
|
|
58
|
+
require an absolute upstream URL`.
|
|
59
|
+
|
|
60
|
+
## Why is snapshot undefined?
|
|
61
|
+
|
|
62
|
+
**Check.** `snapshot` from `c15t/generated` is `undefined`, and the browser
|
|
63
|
+
requests `${backendURL}/manifest` on page load.
|
|
64
|
+
|
|
65
|
+
**Fix.** `snapshot` is `undefined` when Vite has no policy to serve:
|
|
66
|
+
|
|
67
|
+
* `consentManifest` is missing from `plugins` in `vite.config.ts`. Without the
|
|
68
|
+
plugin, `c15t/generated` still resolves, but exports `undefined`.
|
|
69
|
+
* The fetch failed in `vite dev`, or in a build with
|
|
70
|
+
`C15T_ON_BUILD_ERROR=runtime`. The terminal shows a `could not fetch the
|
|
71
|
+
consent manifest` warning.
|
|
72
|
+
* The backend URL is relative, so the plugin skipped the fetch.
|
|
73
|
+
* `consentManifest({ source: 'runtime' })` is set, so the plugin never
|
|
74
|
+
fetches.
|
|
75
|
+
|
|
76
|
+
Fix the cause, then restart `vite dev` or rebuild. The plugin fetches once
|
|
77
|
+
when Vite starts.
|
|
78
|
+
|
|
47
79
|
## The page throws that no IABProvider is mounted
|
|
48
80
|
|
|
49
81
|
The visitor's policy uses the `iab` model and the backend sent its vendor
|
|
@@ -6,8 +6,6 @@ description: Upgrade a React app from c15t v2 (@c15t/react) to v3. Covers
|
|
|
6
6
|
group: frameworks
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
## Hand the upgrade to a coding agent
|
|
10
|
-
|
|
11
9
|
**Upgrade this React app to c15t v3**
|
|
12
10
|
|
|
13
11
|
Paste into Claude Code, Codex, Cursor or another coding agent at the root of your app.
|
|
@@ -15,15 +13,15 @@ Paste into Claude Code, Codex, Cursor or another coding agent at the root of you
|
|
|
15
13
|
```prompt
|
|
16
14
|
Upgrade this React app from c15t v2 to c15t v3.
|
|
17
15
|
|
|
18
|
-
Read
|
|
16
|
+
Read ./upgrade-v3.md first and follow it in order. Do not guess v3 APIs from memory.
|
|
19
17
|
|
|
20
18
|
1. List every c15t dependency and import: `@c15t/react`, `@c15t/scripts`, `@c15t/dev-tools` and `c15t`.
|
|
21
19
|
2. Check that React is 18 or later. Stop and tell me if it needs a major upgrade.
|
|
22
|
-
3. Replace the packages with `c15t
|
|
23
|
-
4. Run `npx @c15t/cli
|
|
20
|
+
3. Replace the packages with `c15t`, plus `@c15t/integrations` if the app uses vendor helpers.
|
|
21
|
+
4. Run `npx @c15t/cli codemods packages-to-c15t consent-provider-options root-exports-to-subpaths use-consent-manager-to-hooks scripts-to-integrations dev-tools-to-c15t policy-packs-to-policy-rules callbacks-to-v3 theme-to-consent-theme iab-option-to-iab-provider css-variables-to-v3 postcss-tailwind3 --dry-run --json`. Review the output, then run the same command without `--dry-run`. The codemods leave a `TODO(c15t v3)` comment wherever they need you to finish a change.
|
|
24
22
|
5. Check that `ConsentManagerProvider` is now `ConsentProvider` from `c15t/react`, with a transport such as `hosted()` as `mode`. Finish any custom mode the codemod marked.
|
|
25
23
|
6. Update callbacks, policy presets, renamed options and components, theme CSS, CSS variables and IAB setup as the guide describes.
|
|
26
|
-
7. Keep the existing backend URL. If the app runs its own c15t backend, stop and tell me, because it has to be upgraded in the same release.
|
|
24
|
+
7. Keep the existing backend URL. If the app runs its own c15t backend, stop and tell me, because it has to be upgraded in the same release with <https://v3.c15t.com/docs/self-host/upgrade-v3.md>.
|
|
27
25
|
8. Run the typecheck and build, and resolve every `TODO(c15t v3)` comment.
|
|
28
26
|
|
|
29
27
|
When you finish, list the files you changed, anything you could not migrate, and how you checked that vendor requests still wait for consent.
|
|
@@ -34,22 +32,21 @@ When you finish, list the files you changed, anything you could not migrate, and
|
|
|
34
32
|
* Upgrade React and React DOM to 18 or later.
|
|
35
33
|
* If you run your own c15t backend, upgrade it in the same release. A v3
|
|
36
34
|
client can't read a v2 backend. See
|
|
37
|
-
[Upgrade a self-hosted backend](
|
|
35
|
+
[Upgrade a self-hosted backend](https://c15t.com/docs/self-host/upgrade-v3).
|
|
38
36
|
Inth-hosted backends need no change.
|
|
39
37
|
|
|
40
38
|
## Replace the packages
|
|
41
39
|
|
|
42
|
-
Remove `@c15t/react` and `@c15t/scripts`, then install `c15t
|
|
43
|
-
`alpha` dist-tag. npm's default tag still resolves v2.
|
|
40
|
+
Remove `@c15t/react` and `@c15t/scripts`, then install `c15t`.
|
|
44
41
|
|
|
45
|
-
| Package manager | Command
|
|
46
|
-
| :-------------- |
|
|
47
|
-
| npm | `npm install c15t
|
|
48
|
-
| pnpm | `pnpm add c15t
|
|
49
|
-
| yarn | `yarn add c15t
|
|
50
|
-
| bun | `bun add c15t
|
|
42
|
+
| Package manager | Command |
|
|
43
|
+
| :-------------- | :------------------------------------ |
|
|
44
|
+
| npm | `npm install c15t @c15t/integrations` |
|
|
45
|
+
| pnpm | `pnpm add c15t @c15t/integrations` |
|
|
46
|
+
| yarn | `yarn add c15t @c15t/integrations` |
|
|
47
|
+
| bun | `bun add c15t @c15t/integrations` |
|
|
51
48
|
|
|
52
|
-
Drop `@c15t/integrations
|
|
49
|
+
Drop `@c15t/integrations` if you don't use its vendor helpers.
|
|
53
50
|
|
|
54
51
|
| v2 import | v3 import |
|
|
55
52
|
| --------------------------------------- | ---------------------------------------------------------------------------------- |
|
|
@@ -59,8 +56,11 @@ Drop `@c15t/integrations@alpha` if you don't use its vendor helpers.
|
|
|
59
56
|
| `DevTools` from `@c15t/dev-tools/react` | `DevTools` from `c15t/react/devtools` |
|
|
60
57
|
| `@c15t/scripts/*` | `@c15t/integrations/*` |
|
|
61
58
|
|
|
62
|
-
|
|
63
|
-
|
|
59
|
+
The `packages-to-c15t` codemod rewrites the `@c15t/react` imports and removes
|
|
60
|
+
the stylesheet import. It doesn't edit `package.json`.
|
|
61
|
+
|
|
62
|
+
`@c15t/react` is still published at v3, so its imports keep working after you
|
|
63
|
+
upgrade it. These docs use `c15t/react`.
|
|
64
64
|
|
|
65
65
|
Every v3 package ships ESM only. If a CommonJS file in your app calls
|
|
66
66
|
`require()` on a c15t package, convert it to ESM.
|
|
@@ -68,15 +68,14 @@ Every v3 package ships ESM only. If a CommonJS file in your app calls
|
|
|
68
68
|
## Rename the integrations dependency
|
|
69
69
|
|
|
70
70
|
v3 renames `@c15t/scripts` to `@c15t/integrations`. Remove `@c15t/scripts`
|
|
71
|
-
from your dependencies and install `@c15t/integrations
|
|
72
|
-
dist-tag:
|
|
71
|
+
from your dependencies and install `@c15t/integrations`:
|
|
73
72
|
|
|
74
|
-
| Package manager | Command
|
|
75
|
-
| :-------------- |
|
|
76
|
-
| npm | `npm install @c15t/integrations
|
|
77
|
-
| pnpm | `pnpm add @c15t/integrations
|
|
78
|
-
| yarn | `yarn add @c15t/integrations
|
|
79
|
-
| bun | `bun add @c15t/integrations
|
|
73
|
+
| Package manager | Command |
|
|
74
|
+
| :-------------- | :------------------------------- |
|
|
75
|
+
| npm | `npm install @c15t/integrations` |
|
|
76
|
+
| pnpm | `pnpm add @c15t/integrations` |
|
|
77
|
+
| yarn | `yarn add @c15t/integrations` |
|
|
78
|
+
| bun | `bun add @c15t/integrations` |
|
|
80
79
|
|
|
81
80
|
Replace the package name in each import. Vendor subpaths and helper names stay
|
|
82
81
|
the same.
|
|
@@ -98,11 +97,11 @@ import { posthog } from '@c15t/integrations/posthog';
|
|
|
98
97
|
The `scripts` configuration option and the `Script` type keep their names.
|
|
99
98
|
|
|
100
99
|
Two helper behaviors change. A helper that needs an ID, such as `metaPixel`,
|
|
101
|
-
`googleTagManager` or `posthog`, now
|
|
102
|
-
whitespace, where v2 loaded a broken script. And if
|
|
103
|
-
`@c15t/integrations/registry`, an entry's `consentCategory` can
|
|
104
|
-
compound condition such as `{ and: ['marketing', 'measurement'] }`,
|
|
105
|
-
category name.
|
|
100
|
+
`googleTagManager` or `posthog`, now logs an error and skips its script when
|
|
101
|
+
the ID is empty or only whitespace, where v2 loaded a broken script. And if
|
|
102
|
+
your code reads `@c15t/integrations/registry`, an entry's `consentCategory` can
|
|
103
|
+
now be a compound condition such as `{ and: ['marketing', 'measurement'] }`,
|
|
104
|
+
not only a category name.
|
|
106
105
|
|
|
107
106
|
`@c15t/scripts` stays available as a deprecated compatibility package for all
|
|
108
107
|
of v3. It re-exports the implementation and types of `@c15t/integrations`, so
|
|
@@ -112,7 +111,7 @@ ends in v4; versions already published stay on npm.
|
|
|
112
111
|
To preview the import changes in JavaScript and TypeScript files:
|
|
113
112
|
|
|
114
113
|
```bash
|
|
115
|
-
npx @c15t/cli
|
|
114
|
+
npx @c15t/cli codemods scripts-to-integrations --dry-run --json
|
|
116
115
|
```
|
|
117
116
|
|
|
118
117
|
Review the output, then run it again without `--dry-run`. The codemod runs
|
|
@@ -127,7 +126,7 @@ that called it re-rendered on every change. v3 has one hook per field. Run the
|
|
|
127
126
|
codemod first:
|
|
128
127
|
|
|
129
128
|
```bash
|
|
130
|
-
npx @c15t/cli
|
|
129
|
+
npx @c15t/cli codemods use-consent-manager-to-hooks --dry-run --json
|
|
131
130
|
```
|
|
132
131
|
|
|
133
132
|
Review the proposed files, then run it again without `--dry-run`. For this v2
|
|
@@ -227,7 +226,7 @@ a transport as `mode`:
|
|
|
227
226
|
|
|
228
227
|
| v2 option | v3 option |
|
|
229
228
|
| ---------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
230
|
-
| `mode: 'hosted'` with `backendURL` | `mode: hosted({
|
|
229
|
+
| `mode: 'hosted'` with `backendURL` | `mode: hosted({ backendURL })` |
|
|
231
230
|
| `mode: 'offline'` with `offlinePolicy` | `mode: offline({ policyRules })` |
|
|
232
231
|
| `mode: 'custom'` with `endpointHandlers` | `mode: custom(transport)`, where `transport` implements the v3 transport interface. `endpointHandlers` throws. |
|
|
233
232
|
|
|
@@ -236,7 +235,7 @@ import { ConsentBanner, ConsentDialog, ConsentProvider, hosted } from 'c15t/reac
|
|
|
236
235
|
|
|
237
236
|
// Replace ConsentManagerProvider:
|
|
238
237
|
<ConsentProvider
|
|
239
|
-
options={{ mode: hosted({
|
|
238
|
+
options={{ mode: hosted({ backendURL: 'https://your-project.c15t.dev' }) }}
|
|
240
239
|
>
|
|
241
240
|
```
|
|
242
241
|
|
|
@@ -245,7 +244,7 @@ and adds the transport import. It can't translate `endpointHandlers`, so it
|
|
|
245
244
|
leaves a `TODO(c15t v3)` comment on a custom mode:
|
|
246
245
|
|
|
247
246
|
```bash
|
|
248
|
-
npx @c15t/cli
|
|
247
|
+
npx @c15t/cli codemods consent-provider-options --dry-run --json
|
|
249
248
|
```
|
|
250
249
|
|
|
251
250
|
Keep your backend URL. An existing hosted URL such as
|
|
@@ -254,6 +253,13 @@ projects use URLs such as `https://your-project.inth.app`. The
|
|
|
254
253
|
[React quickstart](./quickstart.md) shows the full provider,
|
|
255
254
|
and [data fetching](../../concepts/data-fetching.md) covers custom transports.
|
|
256
255
|
|
|
256
|
+
The quickstart keeps `hosted()` and adds `consentManifest()` from
|
|
257
|
+
`c15t/build` to `vite.config.ts`. `hosted()` then reads the backend URL from
|
|
258
|
+
`VITE_C15T_BACKEND_URL`, so it needs no arguments. v3 also adds `manifest()`,
|
|
259
|
+
which bundles the policy when Vite builds. It skips `/init` only when the
|
|
260
|
+
policy has no location rules or the page knows the visitor's location. See
|
|
261
|
+
[consent modes](../../concepts/modes.md).
|
|
262
|
+
|
|
257
263
|
Offline mode keeps choices in the browser and records nothing on a server. Not
|
|
258
264
|
recommended for production environments.
|
|
259
265
|
|
|
@@ -279,7 +285,7 @@ payload, and on `onConsentSet` and `onBannerFetched`, which it can't choose a
|
|
|
279
285
|
replacement for:
|
|
280
286
|
|
|
281
287
|
```bash
|
|
282
|
-
npx @c15t/cli
|
|
288
|
+
npx @c15t/cli codemods callbacks-to-v3 --dry-run --json
|
|
283
289
|
```
|
|
284
290
|
|
|
285
291
|
v2's `onConsentChanged` fired only when a save changed at least one category's
|
|
@@ -336,6 +342,9 @@ const mode = offline({
|
|
|
336
342
|
});
|
|
337
343
|
```
|
|
338
344
|
|
|
345
|
+
In Next.js, import `offline` from `c15t/next` instead and set the result as
|
|
346
|
+
`mode` in `c15t.config.ts`. Both take the same `policyRules`.
|
|
347
|
+
|
|
339
348
|
| v2 preset | v3 preset |
|
|
340
349
|
| ----------------------------------------- | ----------------------- |
|
|
341
350
|
| `europeOptIn()`, `europeIab()` | Same names |
|
|
@@ -362,25 +371,25 @@ between a permission and a recorded choice.
|
|
|
362
371
|
|
|
363
372
|
## Rename options and components
|
|
364
373
|
|
|
365
|
-
| v2 | v3
|
|
366
|
-
| -------------------------------------------------------------------------------------------------- |
|
|
367
|
-
| `translations` | `i18n`
|
|
368
|
-
| `backendURL`, `mode: 'hosted'` | `mode: hosted({
|
|
369
|
-
| `ssrData` (Next.js) | `ConsentRoot` with `state` from `resolveConsent()`
|
|
370
|
-
| `iframeBlockerConfig` | `iframeBlocker`, or `false` to turn it off
|
|
371
|
-
| `Frame`
|
|
372
|
-
| `frame` translations, such as `frame.title` | `consentGate`, such as `consentGate.title`. Copy under `frame` still applies and logs a warning outside production.
|
|
373
|
-
| `FrameTranslations` | `ConsentGateTranslations`. `FrameTranslations` still works as a deprecated alias.
|
|
374
|
-
| `--frame-*` CSS variables | `--consent-gate-*`, with the same suffixes, such as `--consent-gate-placeholder-background-color`. The old names no longer apply.
|
|
375
|
-
| `YouTubeEmbed`, `GoogleMap` | Removed. Wrap your own embed in `ConsentGate`.
|
|
376
|
-
| `useConsentScript()` | Removed. Register the script in `scripts` with a `@c15t/integrations` helper.
|
|
377
|
-
| `useSSRStatus()` | Removed
|
|
378
|
-
| `ConsentButton` | Removed. Use the `ConsentBanner` and `ConsentWidget` buttons, or call `useHeadlessConsentUI()` from your own button.
|
|
379
|
-
| `@c15t/react/cookie-banner` | `c15t/react/consent-banner`
|
|
380
|
-
| `retryConfig` | Removed
|
|
381
|
-
| `store`, including `namespace`, `debug`, `initialConsentCategories` and `initialTranslationConfig` | Removed. Use the top-level `consentCategories` and `i18n` options. Debug information is on `window.c15t`.
|
|
382
|
-
| `window.c15tStore` | `window.c15t`
|
|
383
|
-
| `iab: iab({ ... })` | `IABProvider`. See [Move IAB setup](#move-iab-setup-to-iabprovider).
|
|
374
|
+
| v2 | v3 |
|
|
375
|
+
| -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
376
|
+
| `translations` | `i18n` |
|
|
377
|
+
| `backendURL`, `mode: 'hosted'` | `mode: hosted({ backendURL })` from `c15t/react` on `ConsentProvider`. Next.js `ConsentRoot`: `NEXT_PUBLIC_C15T_BACKEND_URL` and `c15t.config.ts`. |
|
|
378
|
+
| `ssrData` (Next.js) | `ConsentRoot` with `state` from `resolveConsent()` |
|
|
379
|
+
| `iframeBlockerConfig` | `iframeBlocker`, or `false` to turn it off |
|
|
380
|
+
| `Frame`, `FrameRoot`, `FrameTitle`, `FrameButton`, `FrameProps` | `ConsentGate` and its parts. The `Frame` names still work as deprecated aliases and log a one-time warning outside production. |
|
|
381
|
+
| `frame` translations, such as `frame.title` | `consentGate`, such as `consentGate.title`. Copy under `frame` still applies and logs a warning outside production. |
|
|
382
|
+
| `FrameTranslations` | `ConsentGateTranslations`. `FrameTranslations` still works as a deprecated alias. |
|
|
383
|
+
| `--frame-*` CSS variables | `--consent-gate-*`, with the same suffixes, such as `--consent-gate-placeholder-background-color`. The old names no longer apply. |
|
|
384
|
+
| `YouTubeEmbed`, `GoogleMap` | Removed. Wrap your own embed in `ConsentGate`. |
|
|
385
|
+
| `useConsentScript()` | Removed. Register the script in `scripts` with a `@c15t/integrations` helper. |
|
|
386
|
+
| `useSSRStatus()` | Removed |
|
|
387
|
+
| `ConsentButton` | Removed. Use the `ConsentBanner` and `ConsentWidget` buttons, or call `useHeadlessConsentUI()` from your own button. |
|
|
388
|
+
| `@c15t/react/cookie-banner` | `c15t/react/consent-banner` |
|
|
389
|
+
| `retryConfig` | Removed |
|
|
390
|
+
| `store`, including `namespace`, `debug`, `initialConsentCategories` and `initialTranslationConfig` | Removed. Use the top-level `consentCategories` and `i18n` options. Debug information is on `window.c15t`. |
|
|
391
|
+
| `window.c15tStore` | `window.c15t` |
|
|
392
|
+
| `iab: iab({ ... })` | `IABProvider`. See [Move IAB setup](#move-iab-setup-to-iabprovider). |
|
|
384
393
|
|
|
385
394
|
The `consent-provider-options` codemod renames `ConsentManagerProvider` and
|
|
386
395
|
its option and prop types, turns `mode` and `backendURL` into `hosted()` or
|
|
@@ -389,7 +398,7 @@ deprecated `translations` option; the `translations-to-i18n` codemod moves it
|
|
|
389
398
|
to `i18n`.
|
|
390
399
|
|
|
391
400
|
```bash
|
|
392
|
-
npx @c15t/cli
|
|
401
|
+
npx @c15t/cli codemods consent-provider-options translations-to-i18n --dry-run --json
|
|
393
402
|
```
|
|
394
403
|
|
|
395
404
|
`ConsentBanner`, `ConsentDialog`, `ConsentDialogLink`, `ConsentDialogTrigger`
|
|
@@ -417,7 +426,7 @@ The `root-exports-to-subpaths` codemod moves these imports to their new
|
|
|
417
426
|
entries and marks removed names with a `TODO(c15t v3)` comment:
|
|
418
427
|
|
|
419
428
|
```bash
|
|
420
|
-
npx @c15t/cli
|
|
429
|
+
npx @c15t/cli codemods root-exports-to-subpaths --dry-run --json
|
|
421
430
|
```
|
|
422
431
|
|
|
423
432
|
`ConsentGate` changes one behavior from `Frame`. When its category is granted,
|
|
@@ -459,6 +468,9 @@ A generated theme uses `:root:root`, so your own `--c15t-*` values on plain
|
|
|
459
468
|
`styles: false` in the provider options so the components add no second
|
|
460
469
|
copy. See
|
|
461
470
|
[stylesheets and CSS layers](../../customization/stylesheets.md#import-the-stylesheet-yourself).
|
|
471
|
+
The `packages-to-c15t` codemod removes `@c15t/react` and `@c15t/nextjs`
|
|
472
|
+
stylesheet imports. With Tailwind CSS 3 or a cascade layer it keeps them,
|
|
473
|
+
pointed at `c15t`, with a `TODO(c15t v3)` comment.
|
|
462
474
|
* With manual styles, `iab/styles.css` no longer repeats the default tokens.
|
|
463
475
|
Import it after `styles.css`. Automatic IAB styling needs neither import.
|
|
464
476
|
* Tailwind CSS 3 needs a PostCSS plugin for c15t's `styles.css`. Add
|
|
@@ -486,7 +498,7 @@ The `css-variables-to-v3` codemod renames `--consent-widget-*` and
|
|
|
486
498
|
`theme.slots.consentDialogFooter` and marks `theme.slots.frame`.
|
|
487
499
|
|
|
488
500
|
```bash
|
|
489
|
-
npx @c15t/cli
|
|
501
|
+
npx @c15t/cli codemods theme-to-consent-theme css-variables-to-v3 postcss-tailwind3 --dry-run --json
|
|
490
502
|
```
|
|
491
503
|
|
|
492
504
|
`theme.slots` now applies in React. v2 accepted it in types and ignored it, so
|
|
@@ -509,8 +521,8 @@ the CMP doesn't mount, so there is no `__tcfapi` and no TC string.
|
|
|
509
521
|
`@c15t/iab` no longer exports `createIABManager`, `decodeTCString`,
|
|
510
522
|
`generateTCString` or `c15tToIabPurposes`. Use `createIAB({ kernel, cmpId })`,
|
|
511
523
|
which returns a handle with `generateTCString()`, `acceptAll()`, `rejectAll()`
|
|
512
|
-
and `save()`. If your app depends on `@c15t/iab` directly, upgrade it to
|
|
513
|
-
|
|
524
|
+
and `save()`. If your app depends on `@c15t/iab` directly, upgrade it to v3
|
|
525
|
+
too, on the same release as `c15t`. Remove it if
|
|
514
526
|
`IABProvider` now covers everything you used it for.
|
|
515
527
|
|
|
516
528
|
Server integrations now send a reference to the Global Vendor List instead of
|
|
@@ -574,9 +586,45 @@ The `dev-tools-to-c15t` codemod points the imports at `c15t/react/devtools` and
|
|
|
574
586
|
removes the `namespace` prop:
|
|
575
587
|
|
|
576
588
|
```bash
|
|
577
|
-
npx @c15t/cli
|
|
589
|
+
npx @c15t/cli codemods dev-tools-to-c15t --dry-run --json
|
|
578
590
|
```
|
|
579
591
|
|
|
592
|
+
## Upgrade from an earlier v3 alpha
|
|
593
|
+
|
|
594
|
+
The v3 alphas renamed and removed APIs that never shipped in a stable release.
|
|
595
|
+
Names that were in stable v2 keep a deprecated alias. Every other renamed name
|
|
596
|
+
is removed with no alias, so a build that still uses one fails to type-check
|
|
597
|
+
or throws at runtime.
|
|
598
|
+
|
|
599
|
+
### Deprecated, still working
|
|
600
|
+
|
|
601
|
+
Only React's v2 `Frame` names remain. They render `ConsentGate` and, outside
|
|
602
|
+
production, log a one-time warning such as
|
|
603
|
+
``c15t: `Frame` is deprecated and will be removed in a future major release. Use `ConsentGate` instead.``
|
|
604
|
+
|
|
605
|
+
| Package | Deprecated | Use instead |
|
|
606
|
+
| ------------------------------------------------ | ---------------------------------------------------------------------------- | --------------------------------------------------- |
|
|
607
|
+
| `c15t/react`, `c15t/next`, `c15t/tanstack-start` | `Frame`, `FrameRoot`, `FrameTitle`, `FrameButton`, and the `FrameProps` type | `ConsentGate` and its parts, and `ConsentGateProps` |
|
|
608
|
+
|
|
609
|
+
v2's `ConsentManagerProvider` and string modes such as `mode: 'hosted'` are
|
|
610
|
+
handled by the `consent-provider-options` codemod, not by aliases.
|
|
611
|
+
|
|
612
|
+
### Removed
|
|
613
|
+
|
|
614
|
+
| Removed | Use instead |
|
|
615
|
+
| -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
616
|
+
| `hosted({ url })` | `hosted({ backendURL })`, or the framework's backend URL variable |
|
|
617
|
+
| `createManifestTransport({ manifest })` | `createManifestTransport({ snapshot })` |
|
|
618
|
+
| `assertDecisionInputs` defaulting to `false` on `hosted()` | It now defaults to `true` whenever `initURL` is set. Pass `false` to turn it off. |
|
|
619
|
+
| `hostedModes` from `c15t/runtime/provider` | `readHostedMode(mode)` |
|
|
620
|
+
| `buildManifest: true` in Astro and Nuxt | `onBuildError: 'fail'`, the default for production builds. `buildManifest: false` is `manifest({ source: 'runtime' })`. |
|
|
621
|
+
| A generated `c15t-manifest.ts` and its `.gitignore` entry | `import { snapshot } from 'c15t/generated'`. Most apps no longer import it at all. |
|
|
622
|
+
| The build options `outputFile`, `exportName`, `importSource` and `rootDir` | Removed. The snapshot is a virtual module, or a file under `node_modules/.cache/c15t/` in Next.js. |
|
|
623
|
+
|
|
624
|
+
React removes nothing besides the modes above. Import `manifest()` from
|
|
625
|
+
`c15t/react`, next to `hosted()` and `offline()`, instead of from
|
|
626
|
+
`@c15t/browser/headless`; React apps need nothing from `@c15t/browser`.
|
|
627
|
+
|
|
580
628
|
## Update the CLI
|
|
581
629
|
|
|
582
630
|
* Run `c15t login` again. The CLI signs in through Inth now and no longer
|
|
@@ -32,7 +32,7 @@ import type { ReactNode } from 'react';
|
|
|
32
32
|
|
|
33
33
|
import { scripts } from './scripts';
|
|
34
34
|
|
|
35
|
-
const mode = hosted({
|
|
35
|
+
const mode = hosted({ backendURL: 'https://your-project.inth.app' });
|
|
36
36
|
|
|
37
37
|
// `control` is the stock banner. `wall` blocks the page until the visitor
|
|
38
38
|
// chooses.
|
|
@@ -256,7 +256,6 @@ import { resolveConsent } from 'c15t/next/server';
|
|
|
256
256
|
import { Suspense } from 'react';
|
|
257
257
|
import type { ReactNode } from 'react';
|
|
258
258
|
|
|
259
|
-
import { consentOptions } from '@/c15t.server';
|
|
260
259
|
import { ExperimentConsent } from '@/components/experiment-consent';
|
|
261
260
|
import { bannerExperiment } from '@/lib/experiment';
|
|
262
261
|
import { bannerExperimentFlag } from '@/lib/flags';
|
|
@@ -266,7 +265,6 @@ import '@/styles/globals.css';
|
|
|
266
265
|
const ResolvedConsent = async ({ children }: { children: ReactNode }) => {
|
|
267
266
|
const arm = await bannerExperimentFlag();
|
|
268
267
|
const state = await resolveConsent({
|
|
269
|
-
...consentOptions,
|
|
270
268
|
// `off` keeps this visitor out of the experiment.
|
|
271
269
|
experiment: arm === 'off' ? undefined : { ...bannerExperiment, arm },
|
|
272
270
|
});
|
|
@@ -399,6 +397,22 @@ arm re-assigns only the visitors who were in it. For a clean analysis, change
|
|
|
399
397
|
Built-in assignment is not available in Astro; see
|
|
400
398
|
[Astro](#astro).
|
|
401
399
|
|
|
400
|
+
A Vite app's early `/init` script, from `consentManifest()`, picks the arm
|
|
401
|
+
the same way when you pass it the experiment, and the app then runs that
|
|
402
|
+
arm. Import the same object into `vite.config.ts`:
|
|
403
|
+
|
|
404
|
+
```ts title="vite.config.ts"
|
|
405
|
+
consentManifest({ initPrefetch: { experiment: bannerExperiment } });
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
Without it, the app sends its own `/init` for visitors who have not chosen
|
|
409
|
+
yet. The same goes for `consentPrefetchHead` in TanStack Start and
|
|
410
|
+
`buildPrefetchScript` elsewhere, which take the same `experiment` option.
|
|
411
|
+
|
|
412
|
+
When a feature flag picks the arm, leave `experiment` out of
|
|
413
|
+
`initPrefetch`. The script would pick its own arm and send it to the
|
|
414
|
+
backend, and the app would then send a second `/init` with the flag's arm.
|
|
415
|
+
|
|
402
416
|
## Acknowledge presentation diagnostics
|
|
403
417
|
|
|
404
418
|
Each arm is resolved under the visitor's policy the same way `presentation`
|
|
@@ -492,11 +506,12 @@ owed to, and how many of them accepted. c15t sends both to the backend on
|
|
|
492
506
|
its own; you do not wire anything up.
|
|
493
507
|
|
|
494
508
|
* **Visitors owed the banner.** While a visitor has no stored choice, every
|
|
495
|
-
`/init` carries their arm in
|
|
496
|
-
and the backend puts it on that request's session report as
|
|
509
|
+
`/init` carries their arm as `<id>=<arm>` in the `experiment` query
|
|
510
|
+
parameter, and the backend puts it on that request's session report as
|
|
497
511
|
`experiment: { id, arm }`. In manifest mode, the server render or the
|
|
498
512
|
init route puts it on the report it sends to `POST /sessions`. A visitor
|
|
499
|
-
who already chose is not shown the banner, so is not counted.
|
|
513
|
+
who already chose is not shown the banner, so is not counted. A
|
|
514
|
+
server-to-server caller can send the `x-c15t-experiment` header instead.
|
|
500
515
|
* **Choices.** Every choice saved through `POST /subjects` carries the arm
|
|
501
516
|
in `metadata.experiment`, as above.
|
|
502
517
|
|