@c15t/react 3.1.0 → 3.2.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.
Files changed (146) hide show
  1. package/AGENTS.md +35 -5
  2. package/README.md +2 -2
  3. package/dist/component-hooks/use-consent-gate.js +2 -0
  4. package/dist/component-hooks/use-consent-labels.js +2 -0
  5. package/dist/component-hooks/use-consent-text-direction.js +2 -0
  6. package/dist/component-hooks/use-vendors-listed-under.js +2 -0
  7. package/dist/components/consent-gate/atoms.js +1 -1
  8. package/dist/components/consent-gate/consent-gate.js +1 -1
  9. package/dist/components/iab-prompt/atoms/root.js +1 -1
  10. package/dist/components/panel-trigger/atoms/toolbar.js +1 -1
  11. package/dist/components/preferences/atoms/button.js +1 -1
  12. package/dist/components/preferences/atoms/vendor-list.js +1 -1
  13. package/dist/components/prompt/atoms/root.js +1 -1
  14. package/dist/components/prompt/components.js +1 -1
  15. package/dist/components/prompt/policy-actions.js +1 -1
  16. package/dist/components/prompt/prompt.js +1 -1
  17. package/dist/components/prompt/surface-context.js +1 -1
  18. package/dist/components/prompt/use-banner-copy.js +1 -1
  19. package/dist/components/shared/streamed-surface.js +1 -1
  20. package/dist/headless.js +1 -1
  21. package/dist/index-parts/offline.js +1 -1
  22. package/dist/modes.js +1 -1
  23. package/dist/styles.tw3.css +2 -2
  24. package/dist/transports/offline.js +1 -1
  25. package/dist/version.js +1 -1
  26. package/dist-types/component-hooks/use-consent-gate.d.ts +102 -0
  27. package/dist-types/component-hooks/use-consent-labels.d.ts +32 -0
  28. package/dist-types/component-hooks/use-consent-text-direction.d.ts +22 -0
  29. package/dist-types/component-hooks/use-vendors-listed-under.d.ts +30 -0
  30. package/dist-types/components/prompt/atoms/root.d.ts +3 -3
  31. package/dist-types/components/prompt/prompt.d.ts +4 -3
  32. package/dist-types/components/prompt/surface-context.d.ts +1 -14
  33. package/dist-types/components/prompt/use-banner-copy.d.ts +8 -3
  34. package/dist-types/components/shared/streamed-surface.d.ts +47 -10
  35. package/dist-types/headless.d.ts +10 -1
  36. package/dist-types/hooks/use-iab-policy-guard.d.ts +17 -1
  37. package/dist-types/hooks/use-scroll-lock.d.ts +16 -2
  38. package/dist-types/index-parts/offline.d.ts +1 -1
  39. package/dist-types/modes.d.ts +1 -1
  40. package/dist-types/module-hooks/script-loader.d.ts +9 -0
  41. package/dist-types/provider.d.ts +3 -3
  42. package/dist-types/transports/offline.d.ts +2 -2
  43. package/dist-types/version.d.ts +1 -1
  44. package/docs/README.md +35 -5
  45. package/docs/concepts/choose-your-setup.md +9 -9
  46. package/docs/concepts/consent-state.md +81 -9
  47. package/docs/concepts/data-fetching.md +30 -23
  48. package/docs/concepts/modes.md +87 -35
  49. package/docs/customization/recipes.md +4 -4
  50. package/docs/customization/stylesheets.md +42 -3
  51. package/docs/customization/tailwind.md +17 -34
  52. package/docs/customization/translations.md +18 -12
  53. package/docs/frameworks/react/clear-on-revocation.md +3 -2
  54. package/docs/frameworks/react/components/consent-banner.md +3 -3
  55. package/docs/frameworks/react/components/consent-provider.md +29 -29
  56. package/docs/frameworks/react/gpp.md +1 -1
  57. package/docs/frameworks/react/headless.md +146 -19
  58. package/docs/frameworks/react/hooks.md +2 -1
  59. package/docs/frameworks/react/iab.md +8 -1
  60. package/docs/frameworks/react/quickstart.md +2 -2
  61. package/docs/frameworks/react/rendering.md +1 -1
  62. package/docs/frameworks/react/translations.md +9 -9
  63. package/docs/frameworks/react/troubleshooting.md +1 -1
  64. package/docs/frameworks/react/upgrade-v3.md +39 -32
  65. package/docs/frameworks/react/vendor-consent.md +5 -0
  66. package/docs/guides/banner-experiments.md +3 -3
  67. package/docs/guides/troubleshooting.md +3 -2
  68. package/docs/integrations/activecampaign.md +297 -0
  69. package/docs/integrations/ada.md +396 -0
  70. package/docs/integrations/adobe-analytics.md +2 -2
  71. package/docs/integrations/adobe-target.md +460 -0
  72. package/docs/integrations/adroll.md +336 -0
  73. package/docs/integrations/ahrefs-analytics.md +2 -2
  74. package/docs/integrations/amazon-ads.md +424 -0
  75. package/docs/integrations/amplitude.md +2 -2
  76. package/docs/integrations/appcues.md +368 -0
  77. package/docs/integrations/attentive.md +313 -0
  78. package/docs/integrations/building-integrations.md +29 -16
  79. package/docs/integrations/clay.md +305 -0
  80. package/docs/integrations/clearbit.md +3 -3
  81. package/docs/integrations/cloudflare-web-analytics.md +2 -2
  82. package/docs/integrations/cloudflare-zaraz.md +2 -2
  83. package/docs/integrations/crisp.md +2 -2
  84. package/docs/integrations/customer-io.md +369 -0
  85. package/docs/integrations/databuddy.md +127 -52
  86. package/docs/integrations/default-com.md +497 -0
  87. package/docs/integrations/dynamic-yield.md +373 -0
  88. package/docs/integrations/fathom-analytics.md +2 -2
  89. package/docs/integrations/front-chat.md +2 -2
  90. package/docs/integrations/fullstory.md +298 -0
  91. package/docs/integrations/gainsight-px.md +418 -0
  92. package/docs/integrations/google-maps.md +2 -2
  93. package/docs/integrations/google-tag-manager.md +59 -2
  94. package/docs/integrations/google-tag.md +2 -2
  95. package/docs/integrations/gorgias.md +365 -0
  96. package/docs/integrations/heap.md +2 -2
  97. package/docs/integrations/hightouch.md +2 -2
  98. package/docs/integrations/hotjar.md +40 -26
  99. package/docs/integrations/hubspot.md +529 -0
  100. package/docs/integrations/insider.md +550 -0
  101. package/docs/integrations/intercom.md +2 -2
  102. package/docs/integrations/klaviyo.md +2 -2
  103. package/docs/integrations/linkedin-insights.md +2 -2
  104. package/docs/integrations/liveintent.md +327 -0
  105. package/docs/integrations/logrocket.md +2 -2
  106. package/docs/integrations/lucky-orange.md +336 -0
  107. package/docs/integrations/marketo.md +309 -0
  108. package/docs/integrations/matomo-analytics.md +2 -2
  109. package/docs/integrations/meta-pixel.md +2 -2
  110. package/docs/integrations/microsoft-clarity.md +2 -2
  111. package/docs/integrations/microsoft-uet.md +2 -2
  112. package/docs/integrations/mixpanel-analytics.md +2 -2
  113. package/docs/integrations/one-dollar-stats.md +2 -2
  114. package/docs/integrations/openai-pixel.md +2 -2
  115. package/docs/integrations/optimizely.md +411 -0
  116. package/docs/integrations/oracle-eloqua.md +301 -0
  117. package/docs/integrations/overview.md +128 -81
  118. package/docs/integrations/pendo.md +339 -0
  119. package/docs/integrations/pinterest-tag.md +2 -2
  120. package/docs/integrations/pirsch.md +2 -2
  121. package/docs/integrations/plausible-analytics.md +2 -2
  122. package/docs/integrations/posthog.md +2 -2
  123. package/docs/integrations/promptwatch.md +2 -2
  124. package/docs/integrations/rb2b.md +363 -0
  125. package/docs/integrations/reddit-pixel.md +2 -2
  126. package/docs/integrations/rudderstack.md +2 -2
  127. package/docs/integrations/rybbit-analytics.md +2 -2
  128. package/docs/integrations/salesforce-pardot.md +342 -0
  129. package/docs/integrations/segment.md +2 -2
  130. package/docs/integrations/sentry.md +2 -2
  131. package/docs/integrations/shopify.md +323 -0
  132. package/docs/integrations/snapchat-pixel.md +2 -2
  133. package/docs/integrations/statable-analytics.md +345 -0
  134. package/docs/integrations/the-trade-desk.md +328 -0
  135. package/docs/integrations/tiktok-pixel.md +2 -2
  136. package/docs/integrations/umami-analytics.md +2 -2
  137. package/docs/integrations/vector.md +333 -0
  138. package/docs/integrations/vercel-analytics.md +2 -2
  139. package/docs/integrations/vercel-speed-insights.md +7 -2
  140. package/docs/integrations/wisepops.md +416 -0
  141. package/docs/integrations/x-pixel.md +2 -2
  142. package/docs/integrations/youtube.md +2 -2
  143. package/docs/integrations/zendesk.md +359 -0
  144. package/package.json +10 -32
  145. package/dist/components/prompt/resolve-banner-primary-actions.js +0 -1
  146. package/dist-types/components/prompt/resolve-banner-primary-actions.d.ts +0 -14
@@ -0,0 +1,497 @@
1
+ ---
2
+ title: Default
3
+ description: Load the Default Pixel after measurement consent or the standalone
4
+ Forms SDK after functionality consent, configure loading and understand
5
+ withdrawal limits.
6
+ seoTitle: Default Pixel and Forms SDK consent with c15t
7
+ seoDescription: Gate Default Pixel on measurement or the Forms SDK on
8
+ functionality, opt into early Pixel loading, and forward consent with c15t.
9
+ icon: radar
10
+ group: integrations
11
+ ---
12
+
13
+ The `defaultComPixel` helper waits for `measurement` consent by default. The
14
+ standalone `defaultComFormsSdk` helper waits for `functionality` consent. Both
15
+ accept a custom consent condition. The Pixel also offers an opt-in
16
+ `loadMode: 'always'` that loads before consent and keeps form capture available.
17
+ Default identifies companies under its analytics permission and can load Vector
18
+ for people identification under its marketing permission.
19
+
20
+ ## Choose one helper
21
+
22
+ Use `defaultComPixel` for automatic form capture and Default's scheduler
23
+ handoff. The current Pixel detects embedded HubSpot and Marketo forms. Use
24
+ `defaultComFormsSdk` for a standalone SDK installation, such as a custom form,
25
+ Pardot integration or a configured API proxy.
26
+
27
+ Use exactly one helper per document. The first helper that starts loading claims
28
+ the document. This includes a Pixel with `loadMode: 'always'` before consent.
29
+ If both helpers are registered, the conflicting helper logs an error and disables
30
+ its loader before insertion. It makes no loader request and does not initialize
31
+ the SDK. The claim lasts for that document, including after consent withdrawal,
32
+ configuration removal or a client-side route change. A full page navigation or
33
+ reload starts a new document.
34
+
35
+ The SDK loader is also blocked when `window.__defaultPixel__.key` already exists.
36
+ The Pixel loader is blocked when `window.DefaultPixelSDK` already exists.
37
+ Neither helper clears the other script's global configuration.
38
+
39
+ The scripts cannot safely share their consent state in every browser. When a
40
+ Pixel key exists, the SDK initializes during script evaluation and reads consent
41
+ from a cookie. It does not replay the Pixel's queue. Waiting for the Pixel's
42
+ live setter still leaves the SDK's default analytics permission enabled when
43
+ the browser rejects that consent cookie. Use the helpers on separate pages if
44
+ your application needs both installations.
45
+
46
+ Remove direct Default snippets, tag-manager copies and other SDK installations
47
+ before registering either helper. These helpers support the current
48
+ `handshake.default.com` scripts. The legacy `pixel-cdn.default.com` and
49
+ `import-cdn.default.com` scripts use different globals and have no consent API.
50
+
51
+ ## Configure Default
52
+
53
+ Copy your public key from the Default workspace. It is browser configuration,
54
+ not a secret API key. Import your chosen helper from
55
+ `@c15t/integrations/default-com` and register the returned script with c15t.
56
+
57
+ | Package manager | Command |
58
+ | :-------------- | :------------------------------- |
59
+ | npm | `npm install @c15t/integrations` |
60
+ | pnpm | `pnpm add @c15t/integrations` |
61
+ | yarn | `yarn add @c15t/integrations` |
62
+ | bun | `bun add @c15t/integrations` |
63
+
64
+ Choose one of these complete `src/consent-scripts.ts` files. Each exports a
65
+ single Default script. The two snippets are alternatives, so do not combine
66
+ their arrays or register both helpers on the same page.
67
+
68
+ **Pixel**
69
+
70
+ ```ts title="src/consent-scripts.ts"
71
+ import { defaultComPixel } from '@c15t/integrations/default-com';
72
+
73
+ export const scripts = [defaultComPixel({ publicKey: 'YOUR_PUBLIC_KEY' })];
74
+ ```
75
+
76
+ **Forms SDK**
77
+
78
+ ```ts title="src/consent-scripts.ts"
79
+ import { defaultComFormsSdk } from '@c15t/integrations/default-com';
80
+
81
+ export const scripts = [defaultComFormsSdk({ publicKey: 'YOUR_PUBLIC_KEY' })];
82
+ ```
83
+
84
+ ## Register the scripts
85
+
86
+ Complete your [framework quickstart](https://c15t.com/docs/frameworks) first. Keep its Inth
87
+ endpoint, policy, styles and consent UI. Remove the vendor's original script,
88
+ SDK initializer or tag-manager entry, so the vendor loads only through c15t.
89
+
90
+ The vendor pages put the helper in `src/consent-scripts.ts`. If your framework
91
+ quickstart already has a `scripts` array, such as the one in `c15t.config.ts`
92
+ in the Next.js guide, add the helper to that array instead of creating a
93
+ second file.
94
+ The `scripts` export is a configuration, not an initializer. Add it to the c15t provider you already have, at the registration
95
+ point for your framework below. These are edits to that provider, not a second
96
+ provider.
97
+
98
+ **Next.js**
99
+
100
+ Add the configuration to `scripts` in `c15t.config.ts`, next to
101
+ `next.config.ts`:
102
+
103
+ ```ts title="c15t.config.ts"
104
+ import { defineConsentConfig } from 'c15t/next';
105
+ import { scripts } from './src/consent-scripts';
106
+
107
+ export default defineConsentConfig({ scripts });
108
+ ```
109
+
110
+ Keep the rest of your config, such as `mode` and `routePrefix`, in the
111
+ same call. `ConsentRoot` reads the config in the browser, so the layout
112
+ keeps passing only `state`. App Router, Pages Router and static export all
113
+ read the same file. See
114
+ [Next.js scripts and embeds](https://c15t.com/docs/frameworks/next/scripts).
115
+
116
+ **TanStack Start**
117
+
118
+ Import the configuration into your root route and pass it to the existing
119
+ `ConsentRoot` as a top-level prop. Keep the loader from the
120
+ [TanStack Start quickstart](https://c15t.com/docs/frameworks/tanstack-start/quickstart):
121
+
122
+ ```tsx title="src/routes/__root.tsx"
123
+ import { scripts } from '../consent-scripts';
124
+
125
+ <ConsentRoot state={consent} scripts={scripts}>
126
+ ```
127
+
128
+ Import vendor helpers in the root route module, not in a server function.
129
+ A server function's return value must be serializable, and script
130
+ configurations carry callbacks. See
131
+ [TanStack Start scripts](https://c15t.com/docs/frameworks/tanstack-start/scripts).
132
+
133
+ **React**
134
+
135
+ Add the configuration to the existing `ConsentProvider` options, next to
136
+ `mode`:
137
+
138
+ ```tsx title="src/consent.tsx"
139
+ import { scripts } from './consent-scripts';
140
+
141
+ <ConsentProvider options={{ mode, scripts }}>
142
+ ```
143
+
144
+ `mode` is the `manifest()` value from the
145
+ [React quickstart](../frameworks/react/quickstart.md). Keep the banner,
146
+ dialog and preferences link inside the provider. See
147
+ [React scripts and embeds](../frameworks/react/scripts.md).
148
+
149
+ **Nuxt**
150
+
151
+ Register the scripts under the `c15t` key in `app/app.config.ts`. Adjust the
152
+ relative import to where you created `consent-scripts.ts`:
153
+
154
+ ```ts title="app/app.config.ts"
155
+ import { scripts } from '../src/consent-scripts';
156
+
157
+ export default defineAppConfig({
158
+ c15t: { scripts },
159
+ });
160
+ ```
161
+
162
+ The Nuxt module merges this over its options in `nuxt.config.ts` and starts
163
+ one script loader in the browser after hydration, once it has applied the
164
+ visitor's stored choice and privacy signals. Keep `scripts` out of
165
+ `nuxt.config.ts`, which reaches the browser as JSON and drops the vendor
166
+ callbacks. Write the vendor IDs into `consent-scripts.ts`. See
167
+ [Nuxt scripts and embeds](https://c15t.com/docs/frameworks/nuxt/scripts).
168
+
169
+ **Vue**
170
+
171
+ Pass the scripts to the existing `c15tVue` plugin call in `src/main.ts`:
172
+
173
+ ```ts title="src/main.ts"
174
+ import { c15tVue, manifest } from 'c15t/vue/vue-plugin';
175
+ import { scripts } from './consent-scripts';
176
+
177
+ app.use(c15tVue, {
178
+ mode: manifest(),
179
+ scripts,
180
+ });
181
+ ```
182
+
183
+ Keep your existing `mode` and other options. The plugin starts one
184
+ script loader when the app mounts, after it has applied the visitor's stored
185
+ choice. Do not also call `createScriptLoader` from a component. See
186
+ [Vue scripts and embeds](https://c15t.com/docs/frameworks/vue/scripts).
187
+
188
+ **Astro**
189
+
190
+ Add the scripts to the client entrypoint from the
191
+ [Astro quickstart](https://c15t.com/docs/frameworks/astro/quickstart), `src/c15t.client.ts`,
192
+ which the integration finds on its own. Keep `astro.config.mjs` as it is.
193
+ If the module already exports scripts, combine the two arrays.
194
+
195
+ ```ts title="src/c15t.client.ts"
196
+ import type { C15tClientOptionsExtension } from 'c15t/astro';
197
+ import { scripts } from './consent-scripts';
198
+
199
+ export default { scripts } satisfies C15tClientOptionsExtension;
200
+ ```
201
+
202
+ Vendor helpers contain callbacks, and the integration options in
203
+ `astro.config.mjs` are serialized into the page, so do not put helpers in
204
+ the integration's `scripts` option. The integration passes the client
205
+ entrypoint to the one runtime every page shares, including across
206
+ `ClientRouter` navigation.
207
+
208
+ **Svelte**
209
+
210
+ Import the scripts in the component that owns your existing provider and
211
+ pass them as a top-level prop:
212
+
213
+ ```svelte title="src/App.svelte"
214
+ <script lang="ts">
215
+ import { ConsentProvider, manifest } from 'c15t/svelte';
216
+ import { scripts } from './consent-scripts';
217
+ </script>
218
+
219
+ <ConsentProvider mode={manifest()} {scripts}>
220
+ <!-- Keep your application, consent UI and preferences link here. -->
221
+ </ConsentProvider>
222
+ ```
223
+
224
+ Retain the styles and consent UI from the [Svelte quickstart](https://c15t.com/docs/frameworks/svelte/quickstart).
225
+ The provider owns the loader and disposes it on unmount.
226
+
227
+ **SvelteKit**
228
+
229
+ Add the scripts to the existing `ConsentRoot` in the root layout. Keep the
230
+ handle and the layout load from the [SvelteKit quickstart](https://c15t.com/docs/frameworks/sveltekit/quickstart).
231
+
232
+ ```svelte title="src/routes/+layout.svelte"
233
+ <script lang="ts">
234
+ import { ConsentRoot } from 'c15t/svelte';
235
+ import { scripts } from '../consent-scripts';
236
+
237
+ let { children, data } = $props();
238
+ </script>
239
+
240
+ <ConsentRoot state={data.consent} {scripts}>
241
+ {@render children()}
242
+ <!-- Keep your consent UI and preferences link here. -->
243
+ </ConsentRoot>
244
+ ```
245
+
246
+ Import vendor helpers in the layout component, not in `+layout.server.ts`:
247
+ a server load cannot send functions to the browser. Prerendered, static and
248
+ SPA-mode pages use the same `scripts` prop. If you pass an externally owned
249
+ `runtime` to the provider, register scripts when creating that runtime instead.
250
+
251
+ **HTML**
252
+
253
+ The helpers in `@c15t/integrations` are ES modules that need a bundler. On a
254
+ page that loads the c15t script tag, paste the vendor's own snippet instead
255
+ and keep it inert until its category is allowed:
256
+
257
+ ```html
258
+ <script type="text/plain" data-c15t-category="measurement">
259
+ // The vendor's snippet, unchanged
260
+ </script>
261
+ ```
262
+
263
+ Use the category this guide names for the vendor. c15t runs the snippet
264
+ once that category is allowed, and reloads the page when the visitor
265
+ withdraws it. Helper options on this page, such as `loadMode`, do not apply
266
+ to a pasted snippet. See [HTML scripts](https://c15t.com/docs/frameworks/html/scripts).
267
+
268
+ **JavaScript**
269
+
270
+ Pass the scripts to `init()` from `@c15t/browser`, next to your mode:
271
+
272
+ ```ts
273
+ import { init, manifest } from '@c15t/browser';
274
+ import { scripts } from './consent-scripts';
275
+
276
+ const consent = init({
277
+ mode: manifest(),
278
+ scripts,
279
+ });
280
+ ```
281
+
282
+ Keep the mode from your quickstart. With
283
+ `createConsentRuntime` from `c15t/runtime`, pass `scripts` to it instead.
284
+ A kernel you create yourself needs a loader from
285
+ `c15t/modules/script-loader`. Attach one loader per kernel. See
286
+ [JavaScript scripts](https://c15t.com/docs/frameworks/javascript/scripts).
287
+
288
+ Both helpers use the vendor ID `default-com`. The Pixel script ID is
289
+ `default-com`; the standalone SDK script ID is `default-com-forms-sdk`.
290
+
291
+ ## Options
292
+
293
+ | Option | Default | Behavior |
294
+ | ---------------------- | -------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
295
+ | `publicKey` | Required | Public workspace key. The helper trims strings. Missing, blank or non-string values log an error and skip loading while keeping Default listed as a vendor. |
296
+ | `category` | Pixel: `'measurement'`; SDK: `'functionality'` | Optional `IntegrationConsentCondition` on both helpers. Accepts a category or an `and`, `or` or `not` condition. Controls loading and the helper's effective permission. With Pixel `loadMode: 'always'`, it controls permission without delaying the loader. |
297
+ | `loadMode` | Pixel only: `'after-consent'` | `'after-consent'` waits for the chosen category. `'always'` loads before consent and forwards the current permission. The Forms SDK helper has no `loadMode` option. |
298
+ | `scriptUrl` | Pixel: `https://handshake.default.com/index.js`; SDK: `https://handshake.default.com/sdk.js` | Override for a compatible current-generation loader or proxy. Whitespace is trimmed. Blank values use the default. |
299
+ | `schedulerOrigins` | Default's setting | Allowed scheduler origins, forwarded to the selected script. |
300
+ | `autoDisplayScheduler` | Pixel: Default's setting; SDK: `true` | Boolean or an object with a `target` CSS selector or `HTMLElement` and optional `loader` boolean. Forwarded to Default. |
301
+ | `endpoint` | SDK only: Default's setting | API endpoint override for the standalone Forms SDK. Whitespace is trimmed; blank or omitted values use the SDK default. The Pixel helper does not accept this option. |
302
+
303
+ ## Loading and consent forwarding
304
+
305
+ With the default settings, the Pixel creates no Default globals or queues and
306
+ inserts no loader until effective `measurement` consent. The standalone SDK
307
+ waits for effective `functionality` consent. A declared Default vendor switch
308
+ must also be allowed. Override `category` to change either helper's condition.
309
+ For example, require marketing consent before loading the Pixel:
310
+
311
+ ```ts
312
+ defaultComPixel({ publicKey: 'YOUR_PUBLIC_KEY', category: 'marketing' });
313
+ ```
314
+
315
+ When the Pixel starts loading, the helper sets its public key and scheduler
316
+ options, then queues one initial
317
+ `['setConsent', { analytics, marketing }]` command before inserting `index.js`.
318
+ It preserves existing queue entries and an existing consent setter.
319
+
320
+ Once Pixel loading starts, keep its `publicKey`, `scriptUrl`,
321
+ `schedulerOrigins` and `autoDisplayScheduler` unchanged for that document.
322
+ Changing these settings throws an error that requires a page reload. This also
323
+ applies to helpers created before startup and later passed to `updateScripts()`.
324
+ The loader rejects the update before changing existing registrations. Removing
325
+ the helper does not unlock the running Pixel's configuration. Navigate to a new
326
+ document to switch workspaces; the helper does not reload the page itself.
327
+ Equivalent settings and category or consent changes remain supported. Before
328
+ the first permitted load, settings can still change.
329
+
330
+ The standalone SDK helper does not create `window.__defaultPixel__` or set its
331
+ key. After `sdk.js` loads, the helper calls `DefaultPixelSDK.setConsent()` before
332
+ the first `DefaultPixelSDK.init()`. If the visitor withdraws consent during the
333
+ download, the helper forwards denial and waits until the configured category
334
+ and vendor allow the SDK again before calling `init()`.
335
+
336
+ For a live standalone SDK registration whose category and vendor are allowed, changes to
337
+ `publicKey`, `endpoint`, `schedulerOrigins` or `autoDisplayScheduler` call
338
+ `init()` again with consent forwarded first. Recreating the helper with the same
339
+ effective options or changing consent alone does not repeat `init()`. Changes
340
+ made while denied wait for permission.
341
+
342
+ Later `init()` calls update the SDK's configuration without repeating identity
343
+ or session startup. They preserve the current identity and session; changing
344
+ the workspace key does not isolate workspaces. Omitting `endpoint` or
345
+ `schedulerOrigins` on an update restores the SDK defaults. Omitting
346
+ `autoDisplayScheduler` restores `true`, including after an explicit `false` or
347
+ display target.
348
+
349
+ After the SDK loads and its effective permission still applies, the typed
350
+ `window.DefaultPixelSDK` API exposes `submitForm()`, `recordFormInteraction()`,
351
+ `on()` and `scheduler` helpers. `submitForm()` accepts a Pixel form ID, an HTML
352
+ form ID, or both, and returns a promise for a result containing `success` and
353
+ `status`. The promise can reject, and any returned `workflow` is unvalidated
354
+ data typed as `unknown`. A successful request does not prove that Default saved
355
+ a submission or ran a workflow. Verify those results in your own workspace.
356
+ `recordFormInteraction()` returns `Promise<void>` without a result value.
357
+ Scheduler subscriptions and `scheduler.display()` return cleanup functions.
358
+ See the [SDK API reference](https://docs.os.default.com/pixel-sdk-reference) for the
359
+ method options and scheduler event payloads.
360
+
361
+ Every update includes both of Default's consent fields. The helper maps c15t
362
+ `measurement` to Default `analytics` and c15t `marketing` to Default `marketing`.
363
+ When the script lacks effective consent, or the visitor turns the Default vendor
364
+ off, both fields are false. A returning visitor whose grants still apply does
365
+ not receive a temporary denial during bootstrap.
366
+
367
+ With the default Pixel category, granting measurement while denying marketing
368
+ loads the Pixel with `{ analytics: true, marketing: false }`. Default's company
369
+ identification can run, while the forwarded marketing denial prevents new
370
+ Vector loads. To require marketing for the Pixel loader itself, set
371
+ `category: 'marketing'` as shown above.
372
+
373
+ The helpers start through c15t's browser script loader. They do not supply
374
+ pre-hydration server startup code or add Default's generated loader retries.
375
+
376
+ ## Choose when the Pixel loads
377
+
378
+ The Pixel defaults to `loadMode: 'after-consent'`. On a new document, this
379
+ installation sends no Default requests until its category is allowed. A visitor
380
+ who declines or ignores that category cannot use the Pixel's form capture or
381
+ scheduler handoff. Provide a form submission path that works without Default
382
+ if visitors must be able to submit while denied.
383
+
384
+ To follow Default's recommendation to keep form capture available before a
385
+ choice, opt into `loadMode: 'always'` on the Pixel:
386
+
387
+ ```ts
388
+ defaultComPixel({ publicKey: 'YOUR_PUBLIC_KEY', loadMode: 'always' });
389
+ ```
390
+
391
+ This mode requests `https://handshake.default.com/index.js` before consent. The
392
+ Pixel requests its form catalogue from `https://api.default.com` and can capture
393
+ and send form submissions before consent too. Default's analytics and marketing
394
+ permissions do not gate those requests, form capture or scheduler handoffs.
395
+
396
+ c15t still queues both consent fields before inserting the loader. With no
397
+ effective permission, both are false. Subsequent measurement, marketing and
398
+ vendor changes update the forwarded values separately from the loading rule.
399
+ Turning the Default vendor off does not prevent an `always` loader request.
400
+ It sends both fields as false instead.
401
+
402
+ The standalone Forms SDK always waits for its configured category and has no
403
+ `loadMode` option. The Pixel and Forms SDK examples remain alternatives in
404
+ either Pixel loading mode.
405
+
406
+ ## Withdrawal and storage
407
+
408
+ The helpers keep the loader element after withdrawal so they can forward
409
+ `{ analytics: false, marketing: false }` to the loaded consent setter. A later
410
+ grant reuses the loader and preserves the Pixel's live setter. Removing a loader
411
+ element would not stop JavaScript that has already executed.
412
+
413
+ Removing or replacing a standalone SDK registration, or disposing its loader,
414
+ releases that registration's permission. When the final registration leaves,
415
+ the helper forwards denial to the SDK client it owns, even after the loader
416
+ element is detached. A surviving shared registration retains its permission.
417
+ Removing or disposing a pending helper does not initialize the SDK.
418
+
419
+ The standalone Forms SDK stays loaded for the rest of the page after its final
420
+ registration leaves, because running `sdk.js` a second time would leave form
421
+ capture attached to the old client. A later helper with the same `scriptUrl`
422
+ reuses that SDK, so a remount does not request `sdk.js` again. The helper
423
+ forwards the current consent, and calls `init` again only when the SDK options
424
+ changed. A helper with a different `scriptUrl` logs an error, does not
425
+ load and leaves the SDK denied. Reload the page to change the SDK URL.
426
+
427
+ Default says analytics withdrawal clears its visitor and session identity
428
+ cookies and their session-storage copies. The current bundles also remove
429
+ `_dflt_attr` attribution data from local storage. Default retains its
430
+ `_dflt_consent` consent cookie. The Pixel's `_dflt_wi` session cache and pending
431
+ scheduler handoff can remain.
432
+
433
+ Marketing withdrawal prevents later Vector loads. It cannot unload Vector
434
+ after Vector has started, and the helper does not clear the partner's cookies
435
+ or storage. Default's consent API does not block form capture, form-catalogue
436
+ requests or scheduler handoffs. Keep c15t's default `reloadOnConsentRevoked`
437
+ behavior enabled. With reload disabled, loaded scripts and form or partner
438
+ activity can continue until navigation.
439
+
440
+ A reload is required to stop code that already executed. With gated loading,
441
+ the next document does not load Default while its category or vendor is denied.
442
+ With Pixel `loadMode: 'always'`, the next document loads the Pixel again with
443
+ the denied consent values, so reloading does not stop Default requests or form
444
+ capture. Full shutdown requires a new document where the helper is absent or
445
+ uses `loadMode: 'after-consent'` with its permission denied.
446
+
447
+ The scheduler on `book.default.com` has its own storage, including
448
+ `default.reservation`, `_dflt_*` entries and `ph_*` PostHog entries. Default says
449
+ this storage does not follow Pixel consent today. The host page cannot clear
450
+ storage on that origin.
451
+
452
+ ## Verify Default
453
+
454
+ Use your own workspace key and test both a new visit and a returning visit.
455
+ Filter browser Network by `default.com`, then check the following:
456
+
457
+ * With the default Pixel settings, no loader or `__defaultPixel__` global
458
+ should appear before measurement permission. Grant measurement while keeping
459
+ marketing denied. Expect one `index.js` loader and
460
+ `{ analytics: true, marketing: false }`. Marketing alone should not load it.
461
+ * With the default standalone SDK settings, no `sdk.js` loader or
462
+ `DefaultPixelSDK` global should appear before functionality permission.
463
+ Functionality alone should load and initialize it with both tracking fields
464
+ false. Inspect the Pixel queue before its bundle executes, or instrument the
465
+ SDK setter to check that consent arrives before `init()`.
466
+ * Test any custom `category` against that condition. With Pixel
467
+ `loadMode: 'always'`, expect the loader and form-catalogue requests before
468
+ consent, even when the vendor is denied. Confirm that both forwarded fields
469
+ are false until the helper has effective permission.
470
+ * Once the chosen category allows the helper, change measurement and marketing
471
+ separately. Their mapped values should follow the choices. Turn off the
472
+ Default vendor and check that both forwarded values become false.
473
+ * Withdraw the chosen category and confirm the default revocation reload.
474
+ Gated loaders should remain blocked in the next document. An `always` Pixel
475
+ should load again with both fields false. With reload disabled for a test,
476
+ confirm that a later grant reuses the original loader and does not initialize
477
+ the SDK again when its effective options are unchanged.
478
+ * With a live, permitted SDK helper, change its supported configuration and
479
+ verify that later submissions use the new key and endpoint and scheduler
480
+ messages use the new allowed origins. After explicit overrides, omit
481
+ `endpoint` and `schedulerOrigins` to restore SDK defaults, and omit
482
+ `autoDisplayScheduler` to restore `true`. Check that identity and session
483
+ startup do not repeat. Repeat the change while denied and confirm that it
484
+ waits for permission.
485
+
486
+ Default's own homepage key can establish that a loader executes. It does not
487
+ verify your domain configuration, form submission, lead routing, scheduler
488
+ handoff or identification results. Those checks need an owned Default workspace.
489
+ The key's public appearance does not establish authorization to monitor or
490
+ collect against that workspace. Monitoring authorization for the live probe
491
+ remains unverified.
492
+
493
+ Sources: [Pixel installation](https://docs.os.default.com/settings/pixel),
494
+ [SDK API reference](https://docs.os.default.com/pixel-sdk-reference),
495
+ [consent behavior](https://docs.os.default.com/forms/privacy),
496
+ [cookies and storage](https://docs.os.default.com/forms/cookies), and
497
+ [Default privacy policy](https://www.default.com/legal/privacy).