@c15t/react 3.0.0-alpha.5 → 3.0.0-alpha.6
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 +6 -4
- package/dist/component-hooks/use-headless-consent-ui.js +1 -1
- package/dist/components/iab-panel/atoms/vendor-list.js +1 -1
- package/dist/components/iab-panel/hooks/use-gvl-data.js +1 -1
- package/dist/components/iab-panel/index.js +1 -1
- package/dist/components/panel/index.js +1 -1
- package/dist/components/panel-trigger/atoms/toolbar.js +1 -1
- package/dist/components/panel-trigger/atoms/trigger-icons.js +1 -1
- package/dist/components/panel-trigger/panel-trigger.js +1 -1
- package/dist/components/preferences/index.js +1 -1
- package/dist/components/shared/ui/accordion/accordion.js +1 -1
- package/dist/components/shared/ui/collapsible/collapsible.js +1 -1
- package/dist/components/shared/ui/preference-item/preference-item.js +1 -1
- package/dist/components/shared/ui/switch/switch.js +1 -1
- package/dist/components/shared/ui/tabs/tabs.js +1 -1
- package/dist/devtools-launcher.js +2 -0
- package/dist/devtools.js +1 -1
- package/dist/hooks/use-headless-iab-consent-ui.js +1 -1
- package/dist/index-parts/core.js +1 -1
- package/dist/provider.js +1 -1
- package/dist/styles.tw3.css +27 -3
- package/dist/version.js +1 -1
- package/dist-types/component-hooks/use-headless-consent-ui.d.ts +4 -4
- package/dist-types/components/iab-panel/index.d.ts +0 -1
- package/dist-types/components/panel/index.d.ts +0 -1
- package/dist-types/components/panel-trigger/atoms/trigger-icons.d.ts +5 -0
- package/dist-types/components/panel-trigger/panel-trigger.d.ts +0 -8
- package/dist-types/components/preferences/index.d.ts +0 -1
- package/dist-types/components/shared/ui/accordion/accordion.d.ts +0 -1
- package/dist-types/components/shared/ui/collapsible/collapsible.d.ts +0 -1
- package/dist-types/components/shared/ui/preference-item/preference-item.d.ts +0 -1
- package/dist-types/components/shared/ui/switch/switch.d.ts +0 -1
- package/dist-types/components/shared/ui/tabs/tabs.d.ts +0 -1
- package/dist-types/devtools-launcher.d.ts +29 -0
- package/dist-types/hooks/use-iab-manager.d.ts +4 -4
- package/dist-types/hooks.d.ts +27 -5
- package/dist-types/index-parts/core.d.ts +1 -1
- package/dist-types/index.d.ts +1 -1
- package/dist-types/provider.d.ts +12 -1
- package/dist-types/version.d.ts +1 -1
- package/docs/README.md +6 -4
- package/docs/concepts/choose-your-setup.md +22 -5
- package/docs/concepts/consent-state.md +41 -0
- package/docs/concepts/data-fetching.md +34 -11
- package/docs/customization/recipes.md +4 -5
- package/docs/customization/slots.md +3 -2
- package/docs/customization/stylesheets.md +29 -39
- package/docs/customization/tailwind.md +5 -5
- package/docs/customization/tokens.md +1 -1
- package/docs/customization/translations.md +32 -5
- package/docs/frameworks/react/components/consent-dialog-trigger.md +5 -0
- package/docs/frameworks/react/components/consent-dialog.md +2 -1
- package/docs/frameworks/react/components/dev-tools.md +23 -0
- package/docs/frameworks/react/headless.md +4 -4
- package/docs/frameworks/react/hooks.md +10 -5
- package/docs/frameworks/react/iab.md +24 -18
- package/docs/frameworks/react/quickstart.md +77 -16
- package/docs/frameworks/react/rendering.md +82 -11
- package/docs/frameworks/react/scripts.md +8 -3
- package/docs/frameworks/react/upgrade-v3.md +596 -0
- package/docs/frameworks/react/vendor-consent.md +6 -0
- package/docs/guides/banner-experiments.md +26 -5
- package/docs/guides/troubleshooting.md +3 -2
- package/docs/integrations/overview.md +28 -27
- package/docs/integrations/sentry.md +416 -0
- package/docs/upgrade-v3.md +201 -314
- package/package.json +8 -8
|
@@ -8,8 +8,9 @@ group: frameworks
|
|
|
8
8
|
## Before you start
|
|
9
9
|
|
|
10
10
|
This guide sets up a client-rendered React app built with Vite. The browser
|
|
11
|
-
loads the page,
|
|
12
|
-
the
|
|
11
|
+
loads the page, resolves the visitor's policy, then shows the banner or runs
|
|
12
|
+
the scripts the visitor allowed. The build-time step bundles the public
|
|
13
|
+
policy; regional policies may still need a backend location request.
|
|
13
14
|
|
|
14
15
|
* **Next.js or TanStack Start?** Use that framework's guide from the
|
|
15
16
|
[framework list](https://c15t.com/docs/frameworks). Their adapters resolve consent on the
|
|
@@ -26,6 +27,10 @@ the backend URL.
|
|
|
26
27
|
[Choose your setup](../../concepts/choose-your-setup.md#decide-who-runs-the-consent-backend)
|
|
27
28
|
covers self-hosting and offline mode.
|
|
28
29
|
|
|
30
|
+
Build-time manifests are the recommended production setup. Complete the
|
|
31
|
+
[build-time manifest step](#bundle-the-manifest-during-builds) before
|
|
32
|
+
deploying, and rebuild after changing policies, translations or vendors.
|
|
33
|
+
|
|
29
34
|
## Install c15t
|
|
30
35
|
|
|
31
36
|
| Package manager | Command |
|
|
@@ -40,14 +45,12 @@ vendor loaders used below.
|
|
|
40
45
|
|
|
41
46
|
## Register your vendor scripts
|
|
42
47
|
|
|
43
|
-
Create `src/scripts.ts`. PostHog waits for measurement permission
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
once.
|
|
48
|
+
Create `src/scripts.ts`. PostHog waits for measurement permission, so your
|
|
49
|
+
policy must include that category. Remove any other PostHog loader from your
|
|
50
|
+
app so PostHog loads once.
|
|
47
51
|
|
|
48
52
|
```ts title="src/scripts.ts"
|
|
49
53
|
import { posthog } from '@c15t/integrations/posthog';
|
|
50
|
-
import { xPixel } from '@c15t/integrations/x-pixel';
|
|
51
54
|
|
|
52
55
|
export const scripts = [
|
|
53
56
|
posthog({
|
|
@@ -55,13 +58,11 @@ export const scripts = [
|
|
|
55
58
|
initOptions: { cookieless_mode: 'never' },
|
|
56
59
|
loadMode: 'after-consent',
|
|
57
60
|
}),
|
|
58
|
-
xPixel({ pixelId: 'your-pixel-id' }),
|
|
59
61
|
];
|
|
60
62
|
```
|
|
61
63
|
|
|
62
|
-
Replace `phc_your_project_key` with your PostHog project key
|
|
63
|
-
|
|
64
|
-
`region: 'us'` for a US project. Remove the loader for a vendor you don't use.
|
|
64
|
+
Replace `phc_your_project_key` with your PostHog project key. PostHog uses its
|
|
65
|
+
EU host; add `region: 'us'` for a US project.
|
|
65
66
|
|
|
66
67
|
`loadMode: 'after-consent'` keeps the PostHog SDK off the page until the
|
|
67
68
|
visitor allows measurement. `cookieless_mode: 'never'` turns off PostHog's
|
|
@@ -130,6 +131,66 @@ router, render the router inside `Consent` so navigation does not remount the
|
|
|
130
131
|
provider. The stylesheet import in `src/consent.tsx` styles the banner and
|
|
131
132
|
dialog; import it once.
|
|
132
133
|
|
|
134
|
+
## Bundle the manifest during builds
|
|
135
|
+
|
|
136
|
+
The build fetches your public policy once and bundles it, so the server never
|
|
137
|
+
fetches it at runtime.
|
|
138
|
+
|
|
139
|
+
Add `consentManifest` to your existing Vite plugin list:
|
|
140
|
+
|
|
141
|
+
```ts title="vite.config.ts (plugins option)"
|
|
142
|
+
import { consentManifest } from 'c15t/build';
|
|
143
|
+
|
|
144
|
+
export default {
|
|
145
|
+
plugins: [
|
|
146
|
+
// Keep your existing framework plugins here.
|
|
147
|
+
consentManifest({ backendURL: 'https://your-project.inth.app' }),
|
|
148
|
+
],
|
|
149
|
+
};
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
Vite writes `src/c15t-manifest.ts` before compiling, including at development
|
|
153
|
+
startup. Keep the generated file out of Git. Install `@c15t/browser@alpha` for
|
|
154
|
+
its browser manifest transport. In the quickstart's `src/consent.tsx`, replace
|
|
155
|
+
the `hosted()` mode with this factory:
|
|
156
|
+
|
|
157
|
+
```tsx title="src/consent.tsx"
|
|
158
|
+
import { manifest } from '@c15t/browser/headless';
|
|
159
|
+
|
|
160
|
+
import { consentManifest } from './c15t-manifest';
|
|
161
|
+
|
|
162
|
+
const mode = manifest({
|
|
163
|
+
backendURL: 'https://your-project.inth.app',
|
|
164
|
+
manifest: consentManifest,
|
|
165
|
+
});
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Keep passing `mode` to `ConsentProvider`. The browser resolves the snapshot
|
|
169
|
+
without `/manifest` when it has the geography the policy needs, or the policy
|
|
170
|
+
does not depend on geography. Supply known country and region through `inputs`
|
|
171
|
+
or overrides to keep regional resolution on the snapshot.
|
|
172
|
+
|
|
173
|
+
When the required country or region is missing, the transport calls backend
|
|
174
|
+
`/init` and uses its resolved policy and translations. That response can use
|
|
175
|
+
newer backend policy than the build snapshot. This is a full consent resolution,
|
|
176
|
+
so these visitors still wait for a backend round trip.
|
|
177
|
+
|
|
178
|
+
Policy and resolver code are part of the browser bundle.
|
|
179
|
+
|
|
180
|
+
The snapshot is fixed at build time:
|
|
181
|
+
|
|
182
|
+
* Rebuild after changing policies, translations or vendors. If your CI caches
|
|
183
|
+
build output, force a fresh build.
|
|
184
|
+
* The build must reach the backend. A failed fetch fails the build.
|
|
185
|
+
* Consent choices still go to the backend.
|
|
186
|
+
|
|
187
|
+
Run `vite build` or `vite dev` before a standalone `tsc`, `vue-tsc` or
|
|
188
|
+
`svelte-check`; the generated file doesn't exist on a fresh checkout.
|
|
189
|
+
|
|
190
|
+
For policy updates without a rebuild, keep the original `hosted()` factory
|
|
191
|
+
and omit the build plugin. That setup resolves policy through the backend
|
|
192
|
+
`/init` on each page load.
|
|
193
|
+
|
|
133
194
|
## Gate your own features
|
|
134
195
|
|
|
135
196
|
Read a category's permission with `useConsent` inside the provider:
|
|
@@ -155,16 +216,16 @@ then open the site in a private window with DevTools open on the Network tab.
|
|
|
155
216
|
Test under a policy that asks for a choice, such as an EU opt-in policy.
|
|
156
217
|
|
|
157
218
|
1. **Before a choice.** The banner shows. There are no requests to
|
|
158
|
-
`posthog.com
|
|
219
|
+
`posthog.com`.
|
|
159
220
|
2. **Reject All.** The banner closes and the vendor requests stay absent.
|
|
160
221
|
3. **Reload.** The banner stays closed and the vendor requests stay absent.
|
|
161
222
|
4. **Privacy settings.** The footer link opens the dialog with **Analytics** (the
|
|
162
|
-
`measurement` category) and **Marketing** off. Turn on **Analytics** and
|
|
163
|
-
|
|
223
|
+
`measurement` category) and **Marketing** off. Turn on **Analytics** and
|
|
224
|
+
save. PostHog's `array.js` loads.
|
|
164
225
|
5. **Turn Analytics off again.** The page reloads and PostHog does not load.
|
|
165
226
|
|
|
166
|
-
If the banner never appears, check the
|
|
167
|
-
`/init` on your backend URL. [Troubleshooting](./troubleshooting.md)
|
|
227
|
+
If the banner never appears, check the generated policy and any location
|
|
228
|
+
request to `/init` on your backend URL. [Troubleshooting](./troubleshooting.md)
|
|
168
229
|
covers the common causes. [Verify consent](../../guides/verify-consent.md) has the
|
|
169
230
|
full release checklist.
|
|
170
231
|
|
|
@@ -23,14 +23,79 @@ read the visitor's cookie and location on the server, so the banner can be in
|
|
|
23
23
|
the first HTML. [Choose your setup](../../concepts/choose-your-setup.md#server-rendering-or-browser-rendering)
|
|
24
24
|
explains the difference in general terms.
|
|
25
25
|
|
|
26
|
+
## Bundle the manifest during Vite builds
|
|
27
|
+
|
|
28
|
+
The build fetches your public policy once and bundles it, so the server never
|
|
29
|
+
fetches it at runtime.
|
|
30
|
+
|
|
31
|
+
Add `consentManifest` to your existing Vite plugin list:
|
|
32
|
+
|
|
33
|
+
```ts title="vite.config.ts (plugins option)"
|
|
34
|
+
import { consentManifest } from 'c15t/build';
|
|
35
|
+
|
|
36
|
+
export default {
|
|
37
|
+
plugins: [
|
|
38
|
+
// Keep your existing framework plugins here.
|
|
39
|
+
consentManifest({ backendURL: 'https://your-project.inth.app' }),
|
|
40
|
+
],
|
|
41
|
+
};
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Vite writes `src/c15t-manifest.ts` before compiling, including at development
|
|
45
|
+
startup. Keep the generated file out of Git. Install `@c15t/browser@alpha` for
|
|
46
|
+
its browser manifest transport. In the quickstart's `src/consent.tsx`, replace
|
|
47
|
+
the `hosted()` mode with this factory:
|
|
48
|
+
|
|
49
|
+
```tsx title="src/consent.tsx"
|
|
50
|
+
import { manifest } from '@c15t/browser/headless';
|
|
51
|
+
|
|
52
|
+
import { consentManifest } from './c15t-manifest';
|
|
53
|
+
|
|
54
|
+
const mode = manifest({
|
|
55
|
+
backendURL: 'https://your-project.inth.app',
|
|
56
|
+
manifest: consentManifest,
|
|
57
|
+
});
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Keep passing `mode` to `ConsentProvider`. The browser resolves the snapshot
|
|
61
|
+
without `/manifest` when it has the geography the policy needs, or the policy
|
|
62
|
+
does not depend on geography. Supply known country and region through `inputs`
|
|
63
|
+
or overrides to keep regional resolution on the snapshot.
|
|
64
|
+
|
|
65
|
+
When the required country or region is missing, the transport calls backend
|
|
66
|
+
`/init` and uses its resolved policy and translations. That response can use
|
|
67
|
+
newer backend policy than the build snapshot. This is a full consent resolution,
|
|
68
|
+
so these visitors still wait for a backend round trip.
|
|
69
|
+
|
|
70
|
+
Policy and resolver code are part of the browser bundle.
|
|
71
|
+
|
|
72
|
+
The snapshot is fixed at build time:
|
|
73
|
+
|
|
74
|
+
* Rebuild after changing policies, translations or vendors. If your CI caches
|
|
75
|
+
build output, force a fresh build.
|
|
76
|
+
* The build must reach the backend. A failed fetch fails the build.
|
|
77
|
+
* Consent choices still go to the backend.
|
|
78
|
+
|
|
79
|
+
Run `vite build` or `vite dev` before a standalone `tsc`, `vue-tsc` or
|
|
80
|
+
`svelte-check`; the generated file doesn't exist on a fresh checkout.
|
|
81
|
+
|
|
82
|
+
For policy updates without a rebuild, keep the original `hosted()` factory
|
|
83
|
+
and omit the build plugin. That setup resolves policy through the backend
|
|
84
|
+
`/init` on each page load.
|
|
85
|
+
|
|
26
86
|
## Client-rendered apps
|
|
27
87
|
|
|
28
|
-
The [quickstart](./quickstart.md)
|
|
29
|
-
browser
|
|
88
|
+
The recommended [quickstart](./quickstart.md) bundles the
|
|
89
|
+
manifest and resolves it in the browser. See [build-time manifests](#bundle-the-manifest-during-vite-builds).
|
|
90
|
+
|
|
91
|
+
For policy updates without rebuilding, keep `hosted({ url })`. That runtime
|
|
92
|
+
path works as follows:
|
|
30
93
|
|
|
31
94
|
1. The page loads with no consent state. Every optional category is denied.
|
|
32
|
-
2. `ConsentProvider` requests `GET /init` from your backend URL
|
|
33
|
-
picks the visitor's policy
|
|
95
|
+
2. `ConsentProvider` requests `GET /init` from your backend URL while it first
|
|
96
|
+
renders, before the page paints. The backend picks the visitor's policy
|
|
97
|
+
from their location. With an `experiment`, the request waits until the
|
|
98
|
+
provider mounts, because it carries the visitor's arm.
|
|
34
99
|
3. The provider applies the policy and any stored choice. It shows the banner
|
|
35
100
|
if the policy asks for one, and loads the scripts the visitor allowed.
|
|
36
101
|
|
|
@@ -47,8 +112,11 @@ around the outlet. In React Router framework mode that is `app/root.tsx`.
|
|
|
47
112
|
browser takes over after hydration:
|
|
48
113
|
|
|
49
114
|
* The server HTML contains your page but no banner and no consent state.
|
|
50
|
-
* After hydration the browser
|
|
51
|
-
policy asks for one.
|
|
115
|
+
* After hydration the browser resolves the bundled manifest, then shows the
|
|
116
|
+
banner if the policy asks for one. When required country or region is
|
|
117
|
+
missing, it calls `/init` and uses the backend's current policy and
|
|
118
|
+
translations, which can differ from the build snapshot. With `hosted()`,
|
|
119
|
+
it always calls `/init`.
|
|
52
120
|
* The server render and the first browser render agree, so hydration does not
|
|
53
121
|
warn or change a stored choice.
|
|
54
122
|
|
|
@@ -96,8 +164,9 @@ browser path.
|
|
|
96
164
|
## Static and prerendered pages
|
|
97
165
|
|
|
98
166
|
A prerendered page is the same HTML for every visitor, so it cannot contain one
|
|
99
|
-
visitor's consent. Use the quickstart
|
|
100
|
-
backend URL directly, so the static host
|
|
167
|
+
visitor's consent. Use the quickstart's build-time snapshot. Consent saves and
|
|
168
|
+
any `/init` requests go to the backend URL directly, so the static host
|
|
169
|
+
needs no server route. Add the site's
|
|
101
170
|
origin to the trusted origins in your Inth project.
|
|
102
171
|
|
|
103
172
|
Do not cache a response that contains a visitor's consent in a CDN or a shared
|
|
@@ -122,7 +191,9 @@ custom transports.
|
|
|
122
191
|
1. Open the page in a private window and view the page source. In a
|
|
123
192
|
server-rendered app the HTML contains your content and no element with
|
|
124
193
|
`data-testid="consent-banner-root"`.
|
|
125
|
-
2. In DevTools Network,
|
|
126
|
-
|
|
127
|
-
|
|
194
|
+
2. In DevTools Network, confirm there is no `/manifest` request with a
|
|
195
|
+
build-time snapshot. A regional policy may still need an `/init` request
|
|
196
|
+
to resolve consent when geography is missing. With `hosted()`, one `/init`
|
|
197
|
+
request runs unless you supply `initialData`.
|
|
198
|
+
3. The banner appears once the policy resolves. Vendor requests stay absent
|
|
128
199
|
until you allow their category.
|
|
@@ -11,11 +11,10 @@ group: frameworks
|
|
|
11
11
|
Pass vendor loaders to `ConsentProvider` through `options.scripts`. The
|
|
12
12
|
provider loads each script when its category is allowed and removes it when
|
|
13
13
|
the category is denied. The [quickstart](./quickstart.md)
|
|
14
|
-
registers PostHog
|
|
14
|
+
registers PostHog this way:
|
|
15
15
|
|
|
16
16
|
```ts title="src/scripts.ts"
|
|
17
17
|
import { posthog } from '@c15t/integrations/posthog';
|
|
18
|
-
import { xPixel } from '@c15t/integrations/x-pixel';
|
|
19
18
|
|
|
20
19
|
export const scripts = [
|
|
21
20
|
posthog({
|
|
@@ -23,7 +22,6 @@ export const scripts = [
|
|
|
23
22
|
initOptions: { cookieless_mode: 'never' },
|
|
24
23
|
loadMode: 'after-consent',
|
|
25
24
|
}),
|
|
26
|
-
xPixel({ pixelId: 'your-pixel-id' }),
|
|
27
25
|
];
|
|
28
26
|
```
|
|
29
27
|
|
|
@@ -76,6 +74,13 @@ covers a vendor without one.
|
|
|
76
74
|
load before consent and pass the visitor's choice to the vendor. Read the
|
|
77
75
|
vendor's guide; a category on a script does not always mean zero requests.
|
|
78
76
|
|
|
77
|
+
## When the script loader downloads
|
|
78
|
+
|
|
79
|
+
The script loader is a separate chunk, downloaded only when `scripts` is not
|
|
80
|
+
empty. `ConsentProvider` loads it when it mounts. The Next.js and TanStack
|
|
81
|
+
Start `ConsentRoot` start the download earlier, during their first render,
|
|
82
|
+
when the visitor's consent already lets a script run.
|
|
83
|
+
|
|
79
84
|
## Embeds and other requests
|
|
80
85
|
|
|
81
86
|
Scripts cover vendor code c15t loads for you. For the rest:
|