@c15t/scripts 3.0.0-alpha.1 → 3.0.0-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (300) hide show
  1. package/AGENTS.md +129 -59
  2. package/README.md +8 -29
  3. package/SKILL.md +33 -0
  4. package/dist/adobe-analytics.js +2 -0
  5. package/dist/ahrefs-analytics.js +2 -0
  6. package/dist/amplitude.js +2 -0
  7. package/dist/clearbit.js +2 -0
  8. package/dist/cloudflare-web-analytics.js +2 -0
  9. package/dist/cloudflare-zaraz.js +2 -0
  10. package/dist/crisp.js +2 -0
  11. package/dist/databuddy.js +2 -0
  12. package/dist/e2e-test-utils.js +2 -137
  13. package/dist/engine/compile.js +2 -89
  14. package/dist/engine/runtime.js +2 -448
  15. package/dist/events.js +2 -0
  16. package/dist/fathom-analytics.js +2 -0
  17. package/dist/front-chat.js +2 -0
  18. package/dist/google-tag-manager.js +2 -0
  19. package/dist/google-tag.js +2 -0
  20. package/dist/heap.js +2 -0
  21. package/dist/hightouch.js +2 -0
  22. package/dist/hotjar.js +2 -0
  23. package/dist/intercom.js +2 -0
  24. package/dist/klaviyo.js +2 -0
  25. package/dist/linkedin-insights.js +2 -0
  26. package/dist/logrocket.js +2 -0
  27. package/dist/matomo-analytics.js +2 -0
  28. package/dist/meta-pixel.js +2 -0
  29. package/dist/microsoft-clarity.js +2 -0
  30. package/dist/microsoft-uet.js +2 -0
  31. package/dist/mixpanel-analytics.js +2 -0
  32. package/dist/one-dollar-stats.js +2 -0
  33. package/dist/openai-pixel.js +2 -0
  34. package/dist/pinterest-tag.js +2 -0
  35. package/dist/pirsch.js +2 -0
  36. package/dist/plausible-analytics.js +2 -0
  37. package/dist/posthog.js +2 -0
  38. package/dist/promptwatch.js +2 -0
  39. package/dist/reddit-pixel.js +2 -0
  40. package/dist/registry.js +2 -392
  41. package/dist/resolve.js +2 -33
  42. package/dist/rudderstack.js +2 -0
  43. package/dist/rybbit-analytics.js +2 -0
  44. package/dist/segment.js +2 -0
  45. package/dist/snapchat-pixel.js +2 -0
  46. package/dist/tiktok-pixel.js +2 -0
  47. package/dist/types.js +2 -16
  48. package/dist/umami-analytics.js +2 -0
  49. package/dist/vendors/_shared/attributes.js +2 -14
  50. package/dist/vendors/_shared/google-consent.js +2 -27
  51. package/dist/vendors/_shared/install-builders.js +2 -21
  52. package/dist/vendors/_shared/required-id.js +2 -0
  53. package/dist/vendors/_shared/script-url.js +2 -28
  54. package/dist/vendors/ads-and-pixels/linkedin-insights.js +2 -48
  55. package/dist/vendors/ads-and-pixels/meta-pixel.js +2 -153
  56. package/dist/vendors/ads-and-pixels/microsoft-uet.js +2 -110
  57. package/dist/vendors/ads-and-pixels/openai-pixel.js +2 -88
  58. package/dist/vendors/ads-and-pixels/pinterest-tag.js +2 -0
  59. package/dist/vendors/ads-and-pixels/reddit-pixel.js +2 -107
  60. package/dist/vendors/ads-and-pixels/snapchat-pixel.js +2 -87
  61. package/dist/vendors/ads-and-pixels/tiktok-pixel.js +2 -89
  62. package/dist/vendors/ads-and-pixels/x-pixel.js +2 -48
  63. package/dist/vendors/analytics/adobe-analytics.js +2 -49
  64. package/dist/vendors/analytics/ahrefs-analytics.js +2 -27
  65. package/dist/vendors/analytics/amplitude.js +2 -134
  66. package/dist/vendors/analytics/clearbit.js +2 -28
  67. package/dist/vendors/analytics/cloudflare-web-analytics.js +2 -32
  68. package/dist/vendors/analytics/databuddy.js +2 -103
  69. package/dist/vendors/analytics/fathom-analytics.js +2 -35
  70. package/dist/vendors/analytics/google-tag.js +2 -66
  71. package/dist/vendors/analytics/heap.js +2 -134
  72. package/dist/vendors/analytics/hightouch.js +2 -109
  73. package/dist/vendors/analytics/hotjar.js +2 -44
  74. package/dist/vendors/analytics/logrocket.js +2 -58
  75. package/dist/vendors/analytics/matomo-analytics.js +2 -191
  76. package/dist/vendors/analytics/microsoft-clarity.js +2 -100
  77. package/dist/vendors/analytics/mixpanel-analytics.js +2 -93
  78. package/dist/vendors/analytics/one-dollar-stats.js +2 -0
  79. package/dist/vendors/analytics/pirsch.js +2 -67
  80. package/dist/vendors/analytics/plausible-analytics.js +2 -81
  81. package/dist/vendors/analytics/posthog.js +2 -200
  82. package/dist/vendors/analytics/promptwatch.js +2 -29
  83. package/dist/vendors/analytics/rudderstack.js +2 -183
  84. package/dist/vendors/analytics/rybbit-analytics.js +2 -63
  85. package/dist/vendors/analytics/segment.js +2 -56
  86. package/dist/vendors/analytics/umami-analytics.js +2 -39
  87. package/dist/vendors/analytics/vercel-analytics.js +2 -53
  88. package/dist/vendors/email-and-sms/klaviyo.js +2 -0
  89. package/dist/vendors/functional/crisp.js +2 -100
  90. package/dist/vendors/functional/front-chat.js +2 -0
  91. package/dist/vendors/functional/intercom.js +2 -45
  92. package/dist/vendors/tag-managers/cloudflare-zaraz.js +2 -98
  93. package/dist/vendors/tag-managers/google-tag-manager.js +2 -59
  94. package/dist/vercel-analytics.js +2 -0
  95. package/dist/x-pixel.js +2 -0
  96. package/dist-types/adobe-analytics.d.ts +2 -0
  97. package/dist-types/ahrefs-analytics.d.ts +2 -0
  98. package/dist-types/amplitude.d.ts +2 -0
  99. package/dist-types/clearbit.d.ts +2 -0
  100. package/dist-types/cloudflare-web-analytics.d.ts +2 -0
  101. package/dist-types/cloudflare-zaraz.d.ts +2 -0
  102. package/dist-types/crisp.d.ts +2 -0
  103. package/dist-types/databuddy.d.ts +2 -0
  104. package/dist-types/e2e-test-utils.d.ts +2 -0
  105. package/dist-types/engine/compile.d.ts +2 -3
  106. package/dist-types/engine/runtime.d.ts +2 -3
  107. package/dist-types/events.d.ts +2 -0
  108. package/dist-types/fathom-analytics.d.ts +2 -0
  109. package/dist-types/front-chat.d.ts +2 -0
  110. package/dist-types/google-tag-manager.d.ts +2 -0
  111. package/dist-types/google-tag.d.ts +2 -0
  112. package/dist-types/heap.d.ts +2 -0
  113. package/dist-types/hightouch.d.ts +2 -0
  114. package/dist-types/hotjar.d.ts +2 -0
  115. package/dist-types/intercom.d.ts +2 -0
  116. package/dist-types/klaviyo.d.ts +2 -0
  117. package/dist-types/linkedin-insights.d.ts +2 -0
  118. package/dist-types/logrocket.d.ts +2 -0
  119. package/dist-types/matomo-analytics.d.ts +2 -0
  120. package/dist-types/meta-pixel.d.ts +2 -0
  121. package/dist-types/microsoft-clarity.d.ts +2 -0
  122. package/dist-types/microsoft-uet.d.ts +2 -0
  123. package/dist-types/mixpanel-analytics.d.ts +2 -0
  124. package/dist-types/one-dollar-stats.d.ts +2 -0
  125. package/dist-types/openai-pixel.d.ts +2 -0
  126. package/dist-types/pinterest-tag.d.ts +2 -0
  127. package/dist-types/pirsch.d.ts +2 -0
  128. package/dist-types/plausible-analytics.d.ts +2 -0
  129. package/dist-types/posthog.d.ts +2 -0
  130. package/dist-types/promptwatch.d.ts +2 -0
  131. package/dist-types/reddit-pixel.d.ts +2 -0
  132. package/dist-types/registry.d.ts +2 -458
  133. package/dist-types/resolve.d.ts +2 -9
  134. package/dist-types/rudderstack.d.ts +2 -0
  135. package/dist-types/rybbit-analytics.d.ts +2 -0
  136. package/dist-types/segment.d.ts +2 -0
  137. package/dist-types/snapchat-pixel.d.ts +2 -0
  138. package/dist-types/tiktok-pixel.d.ts +2 -0
  139. package/dist-types/types.d.ts +2 -314
  140. package/dist-types/umami-analytics.d.ts +2 -0
  141. package/dist-types/vendors/_shared/attributes.d.ts +2 -35
  142. package/dist-types/vendors/_shared/google-consent.d.ts +2 -47
  143. package/dist-types/vendors/_shared/install-builders.d.ts +2 -30
  144. package/dist-types/vendors/_shared/required-id.d.ts +2 -0
  145. package/dist-types/vendors/_shared/script-url.d.ts +2 -75
  146. package/dist-types/vendors/ads-and-pixels/linkedin-insights.d.ts +2 -92
  147. package/dist-types/vendors/ads-and-pixels/meta-pixel.d.ts +2 -289
  148. package/dist-types/vendors/ads-and-pixels/microsoft-uet.d.ts +2 -105
  149. package/dist-types/vendors/ads-and-pixels/openai-pixel.d.ts +2 -211
  150. package/dist-types/vendors/ads-and-pixels/pinterest-tag.d.ts +2 -0
  151. package/dist-types/vendors/ads-and-pixels/reddit-pixel.d.ts +2 -210
  152. package/dist-types/vendors/ads-and-pixels/snapchat-pixel.d.ts +2 -171
  153. package/dist-types/vendors/ads-and-pixels/tiktok-pixel.d.ts +2 -106
  154. package/dist-types/vendors/ads-and-pixels/x-pixel.d.ts +2 -183
  155. package/dist-types/vendors/analytics/adobe-analytics.d.ts +2 -75
  156. package/dist-types/vendors/analytics/ahrefs-analytics.d.ts +2 -62
  157. package/dist-types/vendors/analytics/amplitude.d.ts +2 -234
  158. package/dist-types/vendors/analytics/clearbit.d.ts +2 -60
  159. package/dist-types/vendors/analytics/cloudflare-web-analytics.d.ts +2 -67
  160. package/dist-types/vendors/analytics/databuddy.d.ts +2 -147
  161. package/dist-types/vendors/analytics/fathom-analytics.d.ts +2 -90
  162. package/dist-types/vendors/analytics/google-tag.d.ts +2 -93
  163. package/dist-types/vendors/analytics/heap.d.ts +2 -316
  164. package/dist-types/vendors/analytics/hightouch.d.ts +2 -285
  165. package/dist-types/vendors/analytics/hotjar.d.ts +2 -73
  166. package/dist-types/vendors/analytics/logrocket.d.ts +2 -101
  167. package/dist-types/vendors/analytics/matomo-analytics.d.ts +2 -41
  168. package/dist-types/vendors/analytics/microsoft-clarity.d.ts +2 -97
  169. package/dist-types/vendors/analytics/mixpanel-analytics.d.ts +2 -113
  170. package/dist-types/vendors/analytics/one-dollar-stats.d.ts +2 -0
  171. package/dist-types/vendors/analytics/pirsch.d.ts +2 -96
  172. package/dist-types/vendors/analytics/plausible-analytics.d.ts +2 -122
  173. package/dist-types/vendors/analytics/posthog.d.ts +2 -175
  174. package/dist-types/vendors/analytics/promptwatch.d.ts +2 -36
  175. package/dist-types/vendors/analytics/rudderstack.d.ts +2 -330
  176. package/dist-types/vendors/analytics/rybbit-analytics.d.ts +2 -82
  177. package/dist-types/vendors/analytics/segment.d.ts +2 -158
  178. package/dist-types/vendors/analytics/umami-analytics.d.ts +2 -93
  179. package/dist-types/vendors/analytics/vercel-analytics.d.ts +2 -66
  180. package/dist-types/vendors/email-and-sms/klaviyo.d.ts +2 -0
  181. package/dist-types/vendors/functional/crisp.d.ts +2 -78
  182. package/dist-types/vendors/functional/front-chat.d.ts +2 -0
  183. package/dist-types/vendors/functional/intercom.d.ts +2 -135
  184. package/dist-types/vendors/tag-managers/cloudflare-zaraz.d.ts +2 -39
  185. package/dist-types/vendors/tag-managers/google-tag-manager.d.ts +2 -94
  186. package/dist-types/vercel-analytics.d.ts +2 -0
  187. package/dist-types/x-pixel.d.ts +2 -0
  188. package/docs/README.md +129 -59
  189. package/docs/assets/v3/bottom-bar.png +0 -0
  190. package/docs/assets/v3/brand-card.png +0 -0
  191. package/docs/assets/v3/brand-preferences.png +0 -0
  192. package/docs/assets/v3/choice-wall.png +0 -0
  193. package/docs/assets/v3/headless-bar-html.png +0 -0
  194. package/docs/assets/v3/headless-bar-mobile.png +0 -0
  195. package/docs/assets/v3/headless-bar.png +0 -0
  196. package/docs/assets/v3/slim-bar.png +0 -0
  197. package/docs/concepts/choose-your-setup.md +87 -0
  198. package/docs/concepts/consent-categories.md +84 -0
  199. package/docs/concepts/consent-state.md +357 -0
  200. package/docs/{guides → concepts}/data-fetching.md +31 -27
  201. package/docs/concepts/how-consent-works.md +123 -0
  202. package/docs/concepts/policies.md +71 -0
  203. package/docs/customization/class-names.md +202 -0
  204. package/docs/customization/dark-mode.md +157 -0
  205. package/docs/customization/motion.md +119 -0
  206. package/docs/customization/overview.md +67 -33
  207. package/docs/customization/recipes.md +839 -47
  208. package/docs/customization/slots.md +216 -35
  209. package/docs/customization/stylesheets.md +147 -0
  210. package/docs/customization/tailwind.md +842 -0
  211. package/docs/customization/tokens.md +166 -36
  212. package/docs/customization/translations.md +61 -3
  213. package/docs/frameworks/astro/embeds.md +160 -0
  214. package/docs/frameworks/astro/network-blocker.md +86 -0
  215. package/docs/frameworks/astro/scripts.md +146 -0
  216. package/docs/frameworks/html/embeds.md +142 -0
  217. package/docs/frameworks/html/network-blocker.md +105 -0
  218. package/docs/frameworks/html/scripts.md +164 -0
  219. package/docs/frameworks/javascript/scripts.md +119 -0
  220. package/docs/frameworks/next/embeds.md +90 -0
  221. package/docs/frameworks/next/network-blocker.md +153 -0
  222. package/docs/frameworks/next/scripts.md +196 -0
  223. package/docs/frameworks/nuxt/embeds.md +81 -0
  224. package/docs/frameworks/nuxt/network-blocker.md +97 -0
  225. package/docs/frameworks/nuxt/scripts.md +89 -0
  226. package/docs/frameworks/react/embeds.md +89 -0
  227. package/docs/frameworks/react/network-blocker.md +140 -0
  228. package/docs/frameworks/react/scripts.md +115 -0
  229. package/docs/frameworks/svelte/embeds.md +96 -0
  230. package/docs/frameworks/svelte/network-blocker.md +141 -0
  231. package/docs/frameworks/svelte/scripts.md +137 -0
  232. package/docs/frameworks/sveltekit/embeds.md +103 -0
  233. package/docs/frameworks/sveltekit/network-blocker.md +149 -0
  234. package/docs/frameworks/sveltekit/scripts.md +141 -0
  235. package/docs/frameworks/tanstack-start/embeds.md +96 -0
  236. package/docs/frameworks/tanstack-start/network-blocker.md +145 -0
  237. package/docs/frameworks/tanstack-start/scripts.md +103 -0
  238. package/docs/frameworks/vue/embeds.md +84 -0
  239. package/docs/frameworks/vue/network-blocker.md +99 -0
  240. package/docs/frameworks/vue/scripts.md +93 -0
  241. package/docs/guides/banner-experiments.md +654 -0
  242. package/docs/guides/troubleshooting.md +120 -47
  243. package/docs/guides/verify-consent.md +81 -49
  244. package/docs/integrations/adobe-analytics.md +168 -160
  245. package/docs/integrations/ahrefs-analytics.md +153 -155
  246. package/docs/integrations/amplitude.md +163 -157
  247. package/docs/integrations/building-integrations.md +136 -37
  248. package/docs/integrations/clearbit.md +155 -155
  249. package/docs/integrations/cloudflare-web-analytics.md +157 -157
  250. package/docs/integrations/cloudflare-zaraz.md +210 -262
  251. package/docs/integrations/crisp.md +165 -159
  252. package/docs/integrations/databuddy.md +158 -174
  253. package/docs/integrations/fathom-analytics.md +159 -157
  254. package/docs/integrations/front-chat.md +322 -0
  255. package/docs/integrations/google-maps.md +119 -84
  256. package/docs/integrations/google-tag-manager.md +179 -164
  257. package/docs/integrations/google-tag.md +164 -161
  258. package/docs/integrations/heap.md +164 -156
  259. package/docs/integrations/hightouch.md +162 -158
  260. package/docs/integrations/hotjar.md +160 -156
  261. package/docs/integrations/intercom.md +184 -154
  262. package/docs/integrations/klaviyo.md +486 -0
  263. package/docs/integrations/linkedin-insights.md +175 -151
  264. package/docs/integrations/logrocket.md +161 -157
  265. package/docs/integrations/matomo-analytics.md +189 -179
  266. package/docs/integrations/meta-pixel.md +189 -151
  267. package/docs/integrations/microsoft-clarity.md +164 -156
  268. package/docs/integrations/microsoft-uet.md +149 -155
  269. package/docs/integrations/mixpanel-analytics.md +156 -161
  270. package/docs/integrations/one-dollar-stats.md +306 -0
  271. package/docs/integrations/openai-pixel.md +205 -302
  272. package/docs/integrations/overview.md +143 -83
  273. package/docs/integrations/pinterest-tag.md +329 -0
  274. package/docs/integrations/pirsch.md +170 -160
  275. package/docs/integrations/plausible-analytics.md +173 -159
  276. package/docs/integrations/posthog.md +227 -242
  277. package/docs/integrations/promptwatch.md +155 -155
  278. package/docs/integrations/reddit-pixel.md +186 -158
  279. package/docs/integrations/rudderstack.md +202 -187
  280. package/docs/integrations/rybbit-analytics.md +172 -161
  281. package/docs/integrations/segment.md +183 -155
  282. package/docs/integrations/snapchat-pixel.md +187 -157
  283. package/docs/integrations/tiktok-pixel.md +172 -151
  284. package/docs/integrations/umami-analytics.md +164 -159
  285. package/docs/integrations/vercel-analytics.md +167 -158
  286. package/docs/integrations/x-pixel.md +177 -151
  287. package/docs/integrations/youtube.md +122 -87
  288. package/docs/upgrade-v3.md +490 -354
  289. package/package.json +12 -236
  290. package/dist-types/__tests__/helpers.d.ts +0 -141
  291. package/docs/assets/v3/brand-bar.png +0 -0
  292. package/docs/assets/v3/mobile-card.png +0 -0
  293. package/docs/assets/v3/preferences.png +0 -0
  294. package/docs/frameworks/javascript/script-loader.md +0 -94
  295. package/docs/frameworks/next/script-loader.md +0 -210
  296. package/docs/frameworks/react/script-loader.md +0 -63
  297. package/docs/guides/consent-state.md +0 -60
  298. package/docs/guides/deployment-modes.md +0 -75
  299. package/docs/integrations/clear-on-revocation.md +0 -167
  300. package/docs/integrations/granular-consent.md +0 -208
@@ -1,30 +1,35 @@
1
1
  ---
2
2
  title: Databuddy
3
- description: Configure Databuddy's initial and updated consent state with c15t v3.
3
+ description: Load the Databuddy SDK on every page with the c15t databuddy
4
+ helper, switch its disabled flag and config from measurement consent, and
5
+ check both in DevTools.
6
+ icon: databuddy
4
7
  group: integrations
5
8
  ---
6
9
 
7
10
  ## Configure Databuddy
8
11
 
9
- Use the client ID for your Databuddy project. Supply both configuration objects
10
- so the initial script load has an explicit allowed and denied state.
12
+ Copy the client ID from your Databuddy project. The helper passes it to the
13
+ script as `data-client-id`. Remove any existing Databuddy script and any code
14
+ that sets `window.databuddyConfig`. The helper seeds that global only when it
15
+ is absent, so an existing value overrides your initial state.
11
16
 
12
- | Package manager | Command |
13
- | :-------------- | :-------------------------- |
14
- | npm | `npm install @c15t/scripts` |
15
- | pnpm | `pnpm add @c15t/scripts` |
16
- | yarn | `yarn add @c15t/scripts` |
17
- | bun | `bun add @c15t/scripts` |
17
+ | Package manager | Command |
18
+ | :-------------- | :------------------------------------- |
19
+ | npm | `npm install @c15t/integrations@alpha` |
20
+ | pnpm | `pnpm add @c15t/integrations@alpha` |
21
+ | yarn | `yarn add @c15t/integrations@alpha` |
22
+ | bun | `bun add @c15t/integrations@alpha` |
18
23
 
19
24
  ```ts title="src/consent-scripts.ts"
20
- import { databuddy } from '@c15t/scripts/databuddy';
25
+ import { databuddy } from '@c15t/integrations/databuddy';
21
26
 
22
27
  export const scripts = [
23
- databuddy({
24
- clientId: 'YOUR_CLIENT_ID',
25
- configWhenGranted: { disabled: false },
26
- configWhenDenied: { disabled: true },
27
- }),
28
+ databuddy({
29
+ clientId: 'YOUR_CLIENT_ID',
30
+ configWhenGranted: { disabled: false },
31
+ configWhenDenied: { disabled: true },
32
+ }),
28
33
  ];
29
34
  ```
30
35
 
@@ -32,11 +37,14 @@ export const scripts = [
32
37
 
33
38
  Complete your [framework quickstart](https://c15t.com/docs/frameworks) first. Keep its Inth
34
39
  endpoint, policy, styles and consent UI. Remove the vendor's original script,
35
- SDK initializer or tag-manager entry so c15t owns loading once.
40
+ SDK initializer or tag-manager entry, so the vendor loads only through c15t.
36
41
 
37
- The `scripts` export in `src/consent-scripts.ts` is a configuration, not an
38
- initializer. Add it to your existing consent owner using the registration point
39
- below. These are partial edits to that owner, not additional providers.
42
+ The vendor pages put the helper in `src/consent-scripts.ts`. If your framework
43
+ quickstart already created a scripts file, such as `lib/scripts.ts` in the
44
+ Next.js guide, add the helper to that array instead of creating a second file.
45
+ The `scripts` export is a configuration, not an initializer. Add it to the c15t provider you already have, at the registration
46
+ point for your framework below. These are edits to that provider, not a second
47
+ provider.
40
48
 
41
49
  **Next.js**
42
50
 
@@ -57,158 +65,106 @@ router guide. Its manifest, init and save URLs stay in effect. Add
57
65
  </ConsentRoot>
58
66
  ```
59
67
 
60
- For a Pages Router or static-export setup using `ConsentProvider`, add
61
- `scripts` to its existing `options` instead. Keep the router-specific setup
62
- from [Next.js script loading](../frameworks/next/script-loader.md).
68
+ App Router, Pages Router and static export all use this `ConsentRoot` in
69
+ the `'use client'` wrapper `components/consent.tsx`. Keep `scripts` there,
70
+ because a Server Component cannot pass script callbacks to it. See
71
+ [Next.js scripts and embeds](../frameworks/next/scripts.md).
63
72
 
64
73
  **TanStack Start**
65
74
 
66
- In your existing root route component, import the scripts alongside
67
- `ConsentRoot`. Keep the server loader from the [TanStack Start quickstart](https://c15t.com/docs/frameworks/tanstack-start/quickstart).
75
+ Import the configuration into your root route and pass it to the existing
76
+ `ConsentRoot` as a top-level prop. Keep the loader, `backendURL` and
77
+ `initRoute` from the [TanStack Start quickstart](https://c15t.com/docs/frameworks/tanstack-start/quickstart):
68
78
 
69
- ```tsx
70
- import { Outlet } from '@tanstack/react-router';
71
- import { ConsentRoot } from 'c15t/tanstack-start';
79
+ ```tsx title="src/routes/__root.tsx"
72
80
  import { scripts } from '../consent-scripts';
73
81
 
74
- function Root() {
75
- const state = Route.useLoaderData();
76
- return (
77
- <ConsentRoot state={state} backendURL={backendURL} initRoute={false} scripts={scripts}>
78
- <Outlet />
79
- {/* Keep your consent banner, dialog and preferences link here. */}
80
- </ConsentRoot>
81
- );
82
- }
82
+ <ConsentRoot
83
+ state={consent}
84
+ backendURL={backendURL}
85
+ initRoute={false}
86
+ scripts={scripts}
87
+ >
83
88
  ```
84
89
 
85
- This edits the existing route. `Route` and `backendURL` come from its setup;
86
- keep the document shell and head components if they are part of your root.
87
- `initRoute={false}` keeps the quickstart's direct-backend initialization.
88
- If your app mounts a consent server route, retain its existing `initRoute`
89
- instead. Do not return script callbacks from a server function or route loader.
90
+ Import vendor helpers in the root route module, not in a server function.
91
+ A server function's return value must be serializable, and script
92
+ configurations carry callbacks. See
93
+ [TanStack Start scripts](../frameworks/tanstack-start/scripts.md).
90
94
 
91
95
  **React**
92
96
 
93
- Import the scripts into your existing provider component:
97
+ Add the configuration to the existing `ConsentProvider` options, next to
98
+ `mode`:
94
99
 
95
- ```ts
96
- import { ConsentProvider } from 'c15t/react';
100
+ ```tsx title="src/consent.tsx"
97
101
  import { scripts } from './consent-scripts';
98
- ```
99
-
100
- Keep the existing options and add `scripts`:
101
102
 
102
- ```tsx
103
- <ConsentProvider options={{ ...consentOptions, scripts }}>
104
- {children}
105
- </ConsentProvider>
103
+ <ConsentProvider options={{ mode, scripts }}>
106
104
  ```
107
105
 
108
- Here `consentOptions` is your existing configuration, including
109
- `mode: hosted({ url: backendURL })`. Keep the banner, dialog and preferences
110
- link inside the provider. See [React script loading](../frameworks/react/script-loader.md).
106
+ `mode` is the `hosted({ url: 'https://your-project.inth.app' })` value
107
+ from the [React quickstart](https://c15t.com/docs/frameworks/react/quickstart). Keep the banner,
108
+ dialog and preferences link inside the provider. See
109
+ [React scripts and embeds](../frameworks/react/scripts.md).
111
110
 
112
111
  **Nuxt**
113
112
 
114
- Attach one loader from the root `app.vue`, after the Nuxt module has
115
- started its browser runtime. This keeps vendor callbacks in application code rather
116
- than serialized `nuxt.config.ts` runtime configuration.
113
+ Register the scripts under the `c15t` key in `app/app.config.ts`. Adjust the
114
+ relative import to where you created `consent-scripts.ts`:
117
115
 
118
- ```vue title="app/app.vue"
119
- <script setup lang="ts">
120
- import { onUnmounted } from 'vue';
121
- import { createScriptLoader } from 'c15t/modules/script-loader';
116
+ ```ts title="app/app.config.ts"
122
117
  import { scripts } from '../src/consent-scripts';
123
118
 
124
- const nuxtApp = useNuxtApp();
125
- const kernel = useConsentKernel();
126
- let loader: ReturnType<typeof createScriptLoader> | undefined;
127
-
128
- const removeMountedHook = nuxtApp.hook('app:mounted', () => {
129
- loader = createScriptLoader({ kernel, scripts });
119
+ export default defineAppConfig({
120
+ c15t: { scripts },
130
121
  });
131
- onUnmounted(() => {
132
- removeMountedHook();
133
- loader?.dispose();
134
- });
135
- </script>
136
-
137
- <template>
138
- <ConsentRoot />
139
- <NuxtPage />
140
- </template>
141
122
  ```
142
123
 
143
- Merge the setup code into your root and retain its footer and preferences
144
- link. `useConsentKernel` is auto-imported by the c15t Nuxt module. Adjust the
145
- relative script import if your `app.vue` is at the project root. This loader
146
- waits until the module has applied browser persistence and privacy signals,
147
- then reads the current snapshot and observes future changes. Do not also register these scripts
148
- in another loader. See the [Nuxt quickstart](https://c15t.com/docs/frameworks/nuxt/quickstart).
124
+ The Nuxt module merges this over its options in `nuxt.config.ts` and starts
125
+ one script loader in the browser after hydration, once it has applied the
126
+ visitor's stored choice and privacy signals. Keep `scripts` out of
127
+ `nuxt.config.ts`, which reaches the browser as JSON and drops the vendor
128
+ callbacks. Write the vendor IDs into `consent-scripts.ts`. See
129
+ [Nuxt scripts and embeds](../frameworks/nuxt/scripts.md).
149
130
 
150
131
  **Vue**
151
132
 
152
- Use the kernel already provided by the Vue plugin. Merge this setup into
153
- `App.vue`, whose lifetime covers the application:
133
+ Pass the scripts to the existing `c15tVue` plugin call in `src/main.ts`:
154
134
 
155
- ```vue title="src/App.vue"
156
- <script setup lang="ts">
157
- import { onMounted, onUnmounted } from 'vue';
158
- import { createScriptLoader } from 'c15t/modules/script-loader';
159
- import { useConsentKernel } from 'c15t/vue/vue-plugin';
160
- import ConsentRoot from 'c15t/vue/consent-root';
135
+ ```ts title="src/main.ts"
161
136
  import { scripts } from './consent-scripts';
162
137
 
163
- const kernel = useConsentKernel();
164
- let loader: ReturnType<typeof createScriptLoader> | undefined;
165
-
166
- onMounted(() => {
167
- loader = createScriptLoader({ kernel, scripts });
138
+ app.use(c15tVue, {
139
+ backendURL: 'https://your-project.inth.app',
140
+ scripts,
168
141
  });
169
- onUnmounted(() => loader?.dispose());
170
- </script>
171
-
172
- <template>
173
- <ConsentRoot />
174
- <main>Your application</main>
175
- </template>
176
142
  ```
177
143
 
178
- Keep your existing page content and preferences link. The plugin still owns
179
- the kernel and persistence; this component owns only the vendor loader.
180
- Do not register the same scripts in plugin configuration as well. See the
181
- [Vue quickstart](https://c15t.com/docs/frameworks/vue/quickstart).
144
+ Keep your existing backend URL and other options. The plugin starts one
145
+ script loader when the app mounts, after it has applied the visitor's stored
146
+ choice. Do not also call `createScriptLoader` from a component. See
147
+ [Vue scripts and embeds](../frameworks/vue/scripts.md).
182
148
 
183
149
  **Astro**
184
150
 
185
- Point the existing Astro integration at a client module. Keep its `mode`,
186
- `ui` and framework integration from the [Astro quickstart](https://c15t.com/docs/frameworks/astro/quickstart).
187
- Import `fileURLToPath` in your Astro configuration:
151
+ Add the scripts to the client entrypoint from the
152
+ [Astro quickstart](https://c15t.com/docs/frameworks/astro/quickstart), the module that the
153
+ integration's `clientEntrypoint` option names. Keep `mode`, `ui` and the
154
+ framework integration in `astro.config.mjs` as they are. If the module
155
+ already exports scripts, combine the two arrays.
188
156
 
189
- ```js title="astro.config.mjs"
190
- import { fileURLToPath } from 'node:url';
191
- ```
192
-
193
- Add this option to the existing `c15t({ ... })` call. Resolve the path from
194
- the configuration file because Astro injects the import into a virtual module:
195
-
196
- ```js
197
- clientEntrypoint: fileURLToPath(new URL('./src/c15t.client.ts', import.meta.url)),
198
- ```
199
-
200
- Export the scripts from that module:
201
-
202
- ```ts title="src/c15t.client.ts"
203
- import type { C15tClientOptionsExtension } from '@c15t/astro';
157
+ ```ts title="src/consent-client.ts"
158
+ import type { C15tClientOptionsExtension } from 'c15t/astro';
204
159
  import { scripts } from './consent-scripts';
205
160
 
206
161
  export default { scripts } satisfies C15tClientOptionsExtension;
207
162
  ```
208
163
 
209
- The integration passes this extension to its shared browser runtime. Vendor
210
- helpers contain callbacks, so do not put them in the serialized `scripts`
211
- option in `astro.config.mjs`. Keep one runtime across consent islands and
164
+ Vendor helpers contain callbacks, and the integration options in
165
+ `astro.config.mjs` are serialized into the page, so do not put helpers in
166
+ the integration's `scripts` option. The integration passes the client
167
+ entrypoint to the one runtime every page shares, including across
212
168
  `ClientRouter` navigation.
213
169
 
214
170
  **Svelte**
@@ -221,9 +177,7 @@ pass them as a top-level prop:
221
177
  import { ConsentManagerProvider, hosted } from '@c15t/svelte';
222
178
  import { scripts } from './consent-scripts';
223
179
 
224
- const backendURL = import.meta.env.VITE_C15T_BACKEND_URL;
225
- if (!backendURL) throw new Error('Set VITE_C15T_BACKEND_URL');
226
- const mode = hosted({ url: backendURL });
180
+ const mode = hosted({ url: 'https://your-project.inth.app' });
227
181
  </script>
228
182
 
229
183
  <ConsentManagerProvider {mode} {scripts}>
@@ -245,7 +199,7 @@ and its serializable prefetch data from the [SvelteKit quickstart](https://c15t.
245
199
  import { scripts } from '../consent-scripts';
246
200
 
247
201
  let { children, data } = $props();
248
- const mode = hosted({ url: data.backendURL });
202
+ const mode = hosted({ url: 'https://your-project.inth.app' });
249
203
  </script>
250
204
 
251
205
  <ConsentManagerProvider {mode} {scripts} prefetch={data.prefetch}>
@@ -254,58 +208,88 @@ and its serializable prefetch data from the [SvelteKit quickstart](https://c15t.
254
208
  </ConsentManagerProvider>
255
209
  ```
256
210
 
257
- Import vendor helpers in the layout component, not in `+layout.server.ts`.
258
- For static hosting, keep your browser-only `mode` setup and omit request
259
- prefetch; the `scripts` prop stays the same. If you pass an externally owned
211
+ Import vendor helpers in the layout component, not in `+layout.server.ts`:
212
+ a server load cannot send functions to the browser. Prerendered, static and
213
+ SPA-mode pages use the same `scripts` prop. If you pass an externally owned
260
214
  `runtime` to the provider, register scripts when creating that runtime instead.
261
215
 
216
+ **HTML**
217
+
218
+ The helpers in `@c15t/integrations` are ES modules that need a bundler. On a
219
+ page that loads the c15t script tag, paste the vendor's own snippet instead
220
+ and keep it inert until its category is allowed:
221
+
222
+ ```html
223
+ <script type="text/plain" data-c15t-category="measurement">
224
+ // The vendor's snippet, unchanged
225
+ </script>
226
+ ```
227
+
228
+ Use the category this guide names for the vendor. c15t runs the snippet
229
+ once that category is allowed, and reloads the page when the visitor
230
+ withdraws it. Helper options on this page, such as `loadMode`, do not apply
231
+ to a pasted snippet. See [HTML scripts](../frameworks/html/scripts.md).
232
+
262
233
  **JavaScript**
263
234
 
264
- Attach the loader to your existing kernel before calling
265
- `kernel.commands.init()`:
235
+ Pass the scripts to `init()` from `@c15t/browser`, next to your backend
236
+ URL:
266
237
 
267
238
  ```ts
268
- import { createScriptLoader } from 'c15t/modules/script-loader';
239
+ import { init } from '@c15t/browser';
269
240
  import { scripts } from './consent-scripts';
270
241
 
271
- const loader = createScriptLoader({ kernel, scripts });
242
+ const consent = init({
243
+ backendURL: 'https://your-project.inth.app',
244
+ scripts,
245
+ });
272
246
  ```
273
247
 
274
- Call `loader.dispose()` when that application instance is destroyed.
275
- `kernel` is the hosted kernel from your quickstart. A provider-owned kernel
276
- already has a loader; do not attach a second one. See
277
- [JavaScript script loading](../frameworks/javascript/script-loader.md).
248
+ Keep the backend URL from your quickstart. With
249
+ `createConsentRuntime` from `c15t/runtime`, pass `scripts` to it instead.
250
+ A kernel you create yourself needs a loader from
251
+ `c15t/modules/script-loader`. Attach one loader per kernel. See
252
+ [JavaScript scripts](../frameworks/javascript/scripts.md).
278
253
 
279
254
  ## Options
280
255
 
281
- | Option | Behavior |
282
- | ------------------- | -------------------------------------------------------- |
283
- | `clientId` | Required project client ID. |
284
- | `configWhenGranted` | Required configuration used when measurement is allowed. |
285
- | `configWhenDenied` | Required configuration used when measurement is denied. |
286
- | `apiUrl` | Defaults to `https://basket.databuddy.cc`. |
287
- | `scriptUrl` | Defaults to `https://cdn.databuddy.cc/databuddy.js`. |
288
-
289
- Use serializable configuration values. The helper seeds
290
- `window.databuddyConfig` before loading only if that global is absent. Remove a
291
- separate global initializer that could override your intended initial state.
292
-
293
- ## Consent behavior
294
-
295
- Databuddy uses `alwaysLoad: true`. The script is requested regardless of
296
- measurement permission. On load and later changes, the helper sets
297
- `window.databuddy.options.disabled` from measurement permission. On consent
298
- changes it also replaces `window.databuddyConfig` with the matching object.
299
-
300
- This helper is not a no-request-before-consent integration. If your requirement
301
- is to prevent even the SDK request, use a
302
- [custom gated integration](./building-integrations.md) and verify
303
- its complete lifecycle.
304
-
305
- ## Verify the integration
306
-
307
- Expect the loader request while consent is denied. Check the initial global
308
- configuration and the SDK's `disabled` value, grant measurement, then revoke it.
309
- Confirm collection follows those transitions and that application event calls
310
- stop after revocation. Test with no pre-existing `databuddyConfig` as well as
311
- with persisted consent. See [consent verification](../guides/verify-consent.md).
256
+ | Option | Default | Behavior |
257
+ | ------------------- | --------------------------------------- | ------------------------------------------------------------------------------------ |
258
+ | `clientId` | Required | Set as `data-client-id`. The helper trims it. Empty or whitespace-only values throw. |
259
+ | `configWhenGranted` | Required | Object set as `window.databuddyConfig` while measurement is allowed. |
260
+ | `configWhenDenied` | Required | Object set as `window.databuddyConfig` while measurement is denied. |
261
+ | `apiUrl` | `https://basket.databuddy.cc` | Collection endpoint, set as `data-api-url`. |
262
+ | `scriptUrl` | `https://cdn.databuddy.cc/databuddy.js` | Loader URL override. A blank value falls back to the default. |
263
+
264
+ ## Loading and revocation
265
+
266
+ `databuddy` uses the `measurement` category with `alwaysLoad`, so the
267
+ Databuddy script loads on every page, before the visitor chooses. Before the
268
+ script loads, the helper sets `window.databuddyConfig` to `configWhenDenied` or
269
+ `configWhenGranted`, unless that global already exists. After the script
270
+ loads, the helper sets `window.databuddy.options.disabled` to `true` without
271
+ measurement permission and to `false` with it. On each later consent change,
272
+ the helper replaces `window.databuddyConfig` with the matching object and
273
+ updates `disabled` again. c15t never removes the script.
274
+
275
+ The Databuddy SDK decides what `disabled` stops. The helper cannot prevent the
276
+ script request before consent. If Databuddy must receive no request before
277
+ consent, write a
278
+ [custom gated integration](./building-integrations.md) instead.
279
+
280
+ ## Verify Databuddy
281
+
282
+ 1. In a private window with an opt-in policy, load the page. `databuddy.js`
283
+ loads from `cdn.databuddy.cc` with your `data-client-id`. In the console,
284
+ `window.databuddyConfig` matches `configWhenDenied` and
285
+ `window.databuddy.options.disabled` is `true`.
286
+ 2. Click Reject, then reload. `disabled` is still `true`, and DevTools Network
287
+ shows no event request to your `apiUrl`.
288
+ 3. Open Privacy settings and allow measurement. Without a reload, `disabled`
289
+ becomes `false`, `window.databuddyConfig` matches `configWhenGranted`, and
290
+ event requests reach your `apiUrl`.
291
+ 4. Turn measurement off again and save. c15t reloads the page, and the new
292
+ page starts with `disabled` set to `true`.
293
+
294
+ See the [consent verification guide](../guides/verify-consent.md) for
295
+ navigation and hosting checks.