@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,45 +1,47 @@
1
1
  ---
2
2
  title: RudderStack
3
- description: Gate the RudderStack browser SDK or map c15t categories to
4
- destination consent IDs.
3
+ description: Load the RudderStack JavaScript SDK after measurement consent with
4
+ the c15t rudderstack helper, or map c15t categories to destination consent
5
+ IDs, and check each mode.
6
+ icon: rudderstack
5
7
  group: integrations
6
8
  ---
7
9
 
8
10
  ## Configure RudderStack
9
11
 
10
- Copy the source write key and HTTPS data plane URL from your RudderStack source.
11
- The default helper waits for measurement permission before loading the SDK.
12
+ Copy the source write key and the HTTPS data plane URL from your RudderStack
13
+ source. Keep control-plane credentials out of the browser.
12
14
 
13
- | Package manager | Command |
14
- | :-------------- | :-------------------------- |
15
- | npm | `npm install @c15t/scripts` |
16
- | pnpm | `pnpm add @c15t/scripts` |
17
- | yarn | `yarn add @c15t/scripts` |
18
- | bun | `bun add @c15t/scripts` |
15
+ | Package manager | Command |
16
+ | :-------------- | :------------------------------------- |
17
+ | npm | `npm install @c15t/integrations@alpha` |
18
+ | pnpm | `pnpm add @c15t/integrations@alpha` |
19
+ | yarn | `yarn add @c15t/integrations@alpha` |
20
+ | bun | `bun add @c15t/integrations@alpha` |
19
21
 
20
22
  ```ts title="src/consent-scripts.ts"
21
- import { rudderstack } from '@c15t/scripts/rudderstack';
23
+ import { rudderstack } from '@c15t/integrations/rudderstack';
22
24
 
23
25
  export const scripts = [
24
- rudderstack({
25
- writeKey: 'YOUR_SOURCE_WRITE_KEY',
26
- dataPlaneUrl: 'https://your-data-plane.example.com',
27
- }),
26
+ rudderstack({
27
+ writeKey: 'YOUR_SOURCE_WRITE_KEY',
28
+ dataPlaneUrl: 'https://your-data-plane.example.com',
29
+ }),
28
30
  ];
29
31
  ```
30
32
 
31
- Replace both values before running the example. Keep secret control-plane
32
- credentials out of the browser.
33
-
34
33
  ## Register the scripts
35
34
 
36
35
  Complete your [framework quickstart](https://c15t.com/docs/frameworks) first. Keep its Inth
37
36
  endpoint, policy, styles and consent UI. Remove the vendor's original script,
38
- SDK initializer or tag-manager entry so c15t owns loading once.
37
+ SDK initializer or tag-manager entry, so the vendor loads only through c15t.
39
38
 
40
- The `scripts` export in `src/consent-scripts.ts` is a configuration, not an
41
- initializer. Add it to your existing consent owner using the registration point
42
- below. These are partial edits to that owner, not additional providers.
39
+ The vendor pages put the helper in `src/consent-scripts.ts`. If your framework
40
+ quickstart already created a scripts file, such as `lib/scripts.ts` in the
41
+ Next.js guide, add the helper to that array instead of creating a second file.
42
+ The `scripts` export is a configuration, not an initializer. Add it to the c15t provider you already have, at the registration
43
+ point for your framework below. These are edits to that provider, not a second
44
+ provider.
43
45
 
44
46
  **Next.js**
45
47
 
@@ -60,158 +62,106 @@ router guide. Its manifest, init and save URLs stay in effect. Add
60
62
  </ConsentRoot>
61
63
  ```
62
64
 
63
- For a Pages Router or static-export setup using `ConsentProvider`, add
64
- `scripts` to its existing `options` instead. Keep the router-specific setup
65
- from [Next.js script loading](../frameworks/next/script-loader.md).
65
+ App Router, Pages Router and static export all use this `ConsentRoot` in
66
+ the `'use client'` wrapper `components/consent.tsx`. Keep `scripts` there,
67
+ because a Server Component cannot pass script callbacks to it. See
68
+ [Next.js scripts and embeds](../frameworks/next/scripts.md).
66
69
 
67
70
  **TanStack Start**
68
71
 
69
- In your existing root route component, import the scripts alongside
70
- `ConsentRoot`. Keep the server loader from the [TanStack Start quickstart](https://c15t.com/docs/frameworks/tanstack-start/quickstart).
72
+ Import the configuration into your root route and pass it to the existing
73
+ `ConsentRoot` as a top-level prop. Keep the loader, `backendURL` and
74
+ `initRoute` from the [TanStack Start quickstart](https://c15t.com/docs/frameworks/tanstack-start/quickstart):
71
75
 
72
- ```tsx
73
- import { Outlet } from '@tanstack/react-router';
74
- import { ConsentRoot } from 'c15t/tanstack-start';
76
+ ```tsx title="src/routes/__root.tsx"
75
77
  import { scripts } from '../consent-scripts';
76
78
 
77
- function Root() {
78
- const state = Route.useLoaderData();
79
- return (
80
- <ConsentRoot state={state} backendURL={backendURL} initRoute={false} scripts={scripts}>
81
- <Outlet />
82
- {/* Keep your consent banner, dialog and preferences link here. */}
83
- </ConsentRoot>
84
- );
85
- }
79
+ <ConsentRoot
80
+ state={consent}
81
+ backendURL={backendURL}
82
+ initRoute={false}
83
+ scripts={scripts}
84
+ >
86
85
  ```
87
86
 
88
- This edits the existing route. `Route` and `backendURL` come from its setup;
89
- keep the document shell and head components if they are part of your root.
90
- `initRoute={false}` keeps the quickstart's direct-backend initialization.
91
- If your app mounts a consent server route, retain its existing `initRoute`
92
- instead. Do not return script callbacks from a server function or route loader.
87
+ Import vendor helpers in the root route module, not in a server function.
88
+ A server function's return value must be serializable, and script
89
+ configurations carry callbacks. See
90
+ [TanStack Start scripts](../frameworks/tanstack-start/scripts.md).
93
91
 
94
92
  **React**
95
93
 
96
- Import the scripts into your existing provider component:
94
+ Add the configuration to the existing `ConsentProvider` options, next to
95
+ `mode`:
97
96
 
98
- ```ts
99
- import { ConsentProvider } from 'c15t/react';
97
+ ```tsx title="src/consent.tsx"
100
98
  import { scripts } from './consent-scripts';
101
- ```
102
-
103
- Keep the existing options and add `scripts`:
104
99
 
105
- ```tsx
106
- <ConsentProvider options={{ ...consentOptions, scripts }}>
107
- {children}
108
- </ConsentProvider>
100
+ <ConsentProvider options={{ mode, scripts }}>
109
101
  ```
110
102
 
111
- Here `consentOptions` is your existing configuration, including
112
- `mode: hosted({ url: backendURL })`. Keep the banner, dialog and preferences
113
- link inside the provider. See [React script loading](../frameworks/react/script-loader.md).
103
+ `mode` is the `hosted({ url: 'https://your-project.inth.app' })` value
104
+ from the [React quickstart](https://c15t.com/docs/frameworks/react/quickstart). Keep the banner,
105
+ dialog and preferences link inside the provider. See
106
+ [React scripts and embeds](../frameworks/react/scripts.md).
114
107
 
115
108
  **Nuxt**
116
109
 
117
- Attach one loader from the root `app.vue`, after the Nuxt module has
118
- started its browser runtime. This keeps vendor callbacks in application code rather
119
- than serialized `nuxt.config.ts` runtime configuration.
110
+ Register the scripts under the `c15t` key in `app/app.config.ts`. Adjust the
111
+ relative import to where you created `consent-scripts.ts`:
120
112
 
121
- ```vue title="app/app.vue"
122
- <script setup lang="ts">
123
- import { onUnmounted } from 'vue';
124
- import { createScriptLoader } from 'c15t/modules/script-loader';
113
+ ```ts title="app/app.config.ts"
125
114
  import { scripts } from '../src/consent-scripts';
126
115
 
127
- const nuxtApp = useNuxtApp();
128
- const kernel = useConsentKernel();
129
- let loader: ReturnType<typeof createScriptLoader> | undefined;
130
-
131
- const removeMountedHook = nuxtApp.hook('app:mounted', () => {
132
- loader = createScriptLoader({ kernel, scripts });
116
+ export default defineAppConfig({
117
+ c15t: { scripts },
133
118
  });
134
- onUnmounted(() => {
135
- removeMountedHook();
136
- loader?.dispose();
137
- });
138
- </script>
139
-
140
- <template>
141
- <ConsentRoot />
142
- <NuxtPage />
143
- </template>
144
119
  ```
145
120
 
146
- Merge the setup code into your root and retain its footer and preferences
147
- link. `useConsentKernel` is auto-imported by the c15t Nuxt module. Adjust the
148
- relative script import if your `app.vue` is at the project root. This loader
149
- waits until the module has applied browser persistence and privacy signals,
150
- then reads the current snapshot and observes future changes. Do not also register these scripts
151
- in another loader. See the [Nuxt quickstart](https://c15t.com/docs/frameworks/nuxt/quickstart).
121
+ The Nuxt module merges this over its options in `nuxt.config.ts` and starts
122
+ one script loader in the browser after hydration, once it has applied the
123
+ visitor's stored choice and privacy signals. Keep `scripts` out of
124
+ `nuxt.config.ts`, which reaches the browser as JSON and drops the vendor
125
+ callbacks. Write the vendor IDs into `consent-scripts.ts`. See
126
+ [Nuxt scripts and embeds](../frameworks/nuxt/scripts.md).
152
127
 
153
128
  **Vue**
154
129
 
155
- Use the kernel already provided by the Vue plugin. Merge this setup into
156
- `App.vue`, whose lifetime covers the application:
130
+ Pass the scripts to the existing `c15tVue` plugin call in `src/main.ts`:
157
131
 
158
- ```vue title="src/App.vue"
159
- <script setup lang="ts">
160
- import { onMounted, onUnmounted } from 'vue';
161
- import { createScriptLoader } from 'c15t/modules/script-loader';
162
- import { useConsentKernel } from 'c15t/vue/vue-plugin';
163
- import ConsentRoot from 'c15t/vue/consent-root';
132
+ ```ts title="src/main.ts"
164
133
  import { scripts } from './consent-scripts';
165
134
 
166
- const kernel = useConsentKernel();
167
- let loader: ReturnType<typeof createScriptLoader> | undefined;
168
-
169
- onMounted(() => {
170
- loader = createScriptLoader({ kernel, scripts });
135
+ app.use(c15tVue, {
136
+ backendURL: 'https://your-project.inth.app',
137
+ scripts,
171
138
  });
172
- onUnmounted(() => loader?.dispose());
173
- </script>
174
-
175
- <template>
176
- <ConsentRoot />
177
- <main>Your application</main>
178
- </template>
179
139
  ```
180
140
 
181
- Keep your existing page content and preferences link. The plugin still owns
182
- the kernel and persistence; this component owns only the vendor loader.
183
- Do not register the same scripts in plugin configuration as well. See the
184
- [Vue quickstart](https://c15t.com/docs/frameworks/vue/quickstart).
141
+ Keep your existing backend URL and other options. The plugin starts one
142
+ script loader when the app mounts, after it has applied the visitor's stored
143
+ choice. Do not also call `createScriptLoader` from a component. See
144
+ [Vue scripts and embeds](../frameworks/vue/scripts.md).
185
145
 
186
146
  **Astro**
187
147
 
188
- Point the existing Astro integration at a client module. Keep its `mode`,
189
- `ui` and framework integration from the [Astro quickstart](https://c15t.com/docs/frameworks/astro/quickstart).
190
- Import `fileURLToPath` in your Astro configuration:
191
-
192
- ```js title="astro.config.mjs"
193
- import { fileURLToPath } from 'node:url';
194
- ```
195
-
196
- Add this option to the existing `c15t({ ... })` call. Resolve the path from
197
- the configuration file because Astro injects the import into a virtual module:
198
-
199
- ```js
200
- clientEntrypoint: fileURLToPath(new URL('./src/c15t.client.ts', import.meta.url)),
201
- ```
202
-
203
- Export the scripts from that module:
148
+ Add the scripts to the client entrypoint from the
149
+ [Astro quickstart](https://c15t.com/docs/frameworks/astro/quickstart), the module that the
150
+ integration's `clientEntrypoint` option names. Keep `mode`, `ui` and the
151
+ framework integration in `astro.config.mjs` as they are. If the module
152
+ already exports scripts, combine the two arrays.
204
153
 
205
- ```ts title="src/c15t.client.ts"
206
- import type { C15tClientOptionsExtension } from '@c15t/astro';
154
+ ```ts title="src/consent-client.ts"
155
+ import type { C15tClientOptionsExtension } from 'c15t/astro';
207
156
  import { scripts } from './consent-scripts';
208
157
 
209
158
  export default { scripts } satisfies C15tClientOptionsExtension;
210
159
  ```
211
160
 
212
- The integration passes this extension to its shared browser runtime. Vendor
213
- helpers contain callbacks, so do not put them in the serialized `scripts`
214
- option in `astro.config.mjs`. Keep one runtime across consent islands and
161
+ Vendor helpers contain callbacks, and the integration options in
162
+ `astro.config.mjs` are serialized into the page, so do not put helpers in
163
+ the integration's `scripts` option. The integration passes the client
164
+ entrypoint to the one runtime every page shares, including across
215
165
  `ClientRouter` navigation.
216
166
 
217
167
  **Svelte**
@@ -224,9 +174,7 @@ pass them as a top-level prop:
224
174
  import { ConsentManagerProvider, hosted } from '@c15t/svelte';
225
175
  import { scripts } from './consent-scripts';
226
176
 
227
- const backendURL = import.meta.env.VITE_C15T_BACKEND_URL;
228
- if (!backendURL) throw new Error('Set VITE_C15T_BACKEND_URL');
229
- const mode = hosted({ url: backendURL });
177
+ const mode = hosted({ url: 'https://your-project.inth.app' });
230
178
  </script>
231
179
 
232
180
  <ConsentManagerProvider {mode} {scripts}>
@@ -248,7 +196,7 @@ and its serializable prefetch data from the [SvelteKit quickstart](https://c15t.
248
196
  import { scripts } from '../consent-scripts';
249
197
 
250
198
  let { children, data } = $props();
251
- const mode = hosted({ url: data.backendURL });
199
+ const mode = hosted({ url: 'https://your-project.inth.app' });
252
200
  </script>
253
201
 
254
202
  <ConsentManagerProvider {mode} {scripts} prefetch={data.prefetch}>
@@ -257,72 +205,139 @@ and its serializable prefetch data from the [SvelteKit quickstart](https://c15t.
257
205
  </ConsentManagerProvider>
258
206
  ```
259
207
 
260
- Import vendor helpers in the layout component, not in `+layout.server.ts`.
261
- For static hosting, keep your browser-only `mode` setup and omit request
262
- prefetch; the `scripts` prop stays the same. If you pass an externally owned
208
+ Import vendor helpers in the layout component, not in `+layout.server.ts`:
209
+ a server load cannot send functions to the browser. Prerendered, static and
210
+ SPA-mode pages use the same `scripts` prop. If you pass an externally owned
263
211
  `runtime` to the provider, register scripts when creating that runtime instead.
264
212
 
213
+ **HTML**
214
+
215
+ The helpers in `@c15t/integrations` are ES modules that need a bundler. On a
216
+ page that loads the c15t script tag, paste the vendor's own snippet instead
217
+ and keep it inert until its category is allowed:
218
+
219
+ ```html
220
+ <script type="text/plain" data-c15t-category="measurement">
221
+ // The vendor's snippet, unchanged
222
+ </script>
223
+ ```
224
+
225
+ Use the category this guide names for the vendor. c15t runs the snippet
226
+ once that category is allowed, and reloads the page when the visitor
227
+ withdraws it. Helper options on this page, such as `loadMode`, do not apply
228
+ to a pasted snippet. See [HTML scripts](../frameworks/html/scripts.md).
229
+
265
230
  **JavaScript**
266
231
 
267
- Attach the loader to your existing kernel before calling
268
- `kernel.commands.init()`:
232
+ Pass the scripts to `init()` from `@c15t/browser`, next to your backend
233
+ URL:
269
234
 
270
235
  ```ts
271
- import { createScriptLoader } from 'c15t/modules/script-loader';
236
+ import { init } from '@c15t/browser';
272
237
  import { scripts } from './consent-scripts';
273
238
 
274
- const loader = createScriptLoader({ kernel, scripts });
239
+ const consent = init({
240
+ backendURL: 'https://your-project.inth.app',
241
+ scripts,
242
+ });
275
243
  ```
276
244
 
277
- Call `loader.dispose()` when that application instance is destroyed.
278
- `kernel` is the hosted kernel from your quickstart. A provider-owned kernel
279
- already has a loader; do not attach a second one. See
280
- [JavaScript script loading](../frameworks/javascript/script-loader.md).
245
+ Keep the backend URL from your quickstart. With
246
+ `createConsentRuntime` from `c15t/runtime`, pass `scripts` to it instead.
247
+ A kernel you create yourself needs a loader from
248
+ `c15t/modules/script-loader`. Attach one loader per kernel. See
249
+ [JavaScript scripts](../frameworks/javascript/scripts.md).
281
250
 
282
- ## Map destination consent when loading before permission
251
+ ## Options
283
252
 
284
- `consentManagement` changes the loading contract. The SDK loads immediately,
285
- receives pre-consent configuration, and stays loaded after revocation. c15t
286
- sends consent updates through `rudderanalytics.consent()`.
253
+ | Option | Default | Behavior |
254
+ | ------------------- | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
255
+ | `writeKey` | Required | Source write key. Surrounding whitespace is trimmed; an empty value throws. |
256
+ | `dataPlaneUrl` | Required | Data plane URL. A missing, invalid or non-HTTPS URL throws. |
257
+ | `consentManagement` | None | `{ mapping }` from c15t categories to RudderStack consent IDs. Switches to destination consent mode. |
258
+ | `loadOptions` | `{}` | Third argument to `rudderanalytics.load()`. Use JSON-serializable values only. |
259
+ | `trackPageView` | `true` | Queues `rudderanalytics.page()` before the loader. |
260
+ | `scriptUrl` | `https://cdn.rudderlabs.com/v3/modern/rsa.min.js` | Loader URL override. A non-HTTPS URL throws; a blank value uses the default. |
287
261
 
288
- ```ts title="src/consent-scripts.ts"
289
- import { rudderstack } from '@c15t/scripts/rudderstack';
262
+ ## Loading and revocation
290
263
 
291
- export const scripts = [
292
- rudderstack({
293
- writeKey: 'YOUR_SOURCE_WRITE_KEY',
294
- dataPlaneUrl: 'https://your-data-plane.example.com',
295
- consentManagement: {
296
- mapping: {
297
- measurement: ['product-analytics'],
298
- marketing: ['advertising'],
299
- },
300
- },
301
- }),
302
- ];
303
- ```
264
+ `rudderstack` uses the `measurement` category. `consentManagement` picks the
265
+ mode:
304
266
 
305
- The IDs in this example are placeholders for your destination consent settings.
306
- Allowed c15t categories contribute their IDs to `allowedConsentIds`; denied
307
- categories contribute theirs to `deniedConsentIds`. Test each destination
308
- independently. This mode does not prevent the initial SDK request.
267
+ | Mode | Loads | On consent change | On revocation |
268
+ | ------------------- | ----------------------------------------------------------- | ----------------------------------------------------- | --------------------------------------------------------------- |
269
+ | Default | After measurement is allowed, with `load` and `page` queued | Nothing | Removes the script element and calls no RudderStack API |
270
+ | `consentManagement` | On every page, in RudderStack's pre-consent state | Calls `rudderanalytics.consent()` with the mapped IDs | Keeps the SDK and calls `consent()` with the revoked IDs denied |
309
271
 
310
- ## Options
272
+ ## Map destination consent
273
+
274
+ `consentManagement` loads the RudderStack SDK before the visitor chooses. Use
275
+ it only when every destination in your workspace carries a consent ID from the
276
+ mapping; c15t cannot check destination settings from the browser. Add the
277
+ mapping to the helper call:
278
+
279
+ ```ts
280
+ rudderstack({
281
+ writeKey: 'YOUR_SOURCE_WRITE_KEY',
282
+ dataPlaneUrl: 'https://your-data-plane.example.com',
283
+ consentManagement: {
284
+ mapping: {
285
+ measurement: ['YOUR_ANALYTICS_CONSENT_ID'],
286
+ marketing: ['YOUR_ADVERTISING_CONSENT_ID'],
287
+ },
288
+ },
289
+ });
290
+ ```
311
291
 
312
- | Option | Behavior |
313
- | --------------------------- | ----------------------------------------------------------------------------- |
314
- | `writeKey` | Required non-empty browser source key. |
315
- | `dataPlaneUrl` | Required HTTPS data plane URL. |
316
- | `consentManagement.mapping` | Optional category-to-consent-ID map. Enables pre-consent loading. |
317
- | `loadOptions` | Optional JSON-serializable SDK options; functions are not supported. |
318
- | `trackPageView` | Defaults to `true`, queuing an initial `page()` call. |
319
- | `scriptUrl` | Optional HTTPS loader override. Defaults to the modern v3 RudderStack loader. |
320
-
321
- ## Verify the integration
322
-
323
- In the default mode, confirm denial prevents the initial SDK load. With a
324
- consent mapping, expect the SDK request and inspect the destination consent IDs
325
- instead. The default mode has no vendor shutdown hook after loading, so verify
326
- revocation beyond script removal. In both modes, check routing for duplicate
327
- page events and stop disallowed application events. See
328
- [consent verification](../guides/verify-consent.md).
292
+ The helper sets `preConsent.enabled`, buffered event delivery and
293
+ `consentManagement.provider: 'custom'` in the load options. Storage defaults to
294
+ `{ strategy: 'none' }`; a `preConsent.storage` value in `loadOptions` replaces
295
+ it. Before `load`, the helper queues a `consent()` call. IDs of allowed
296
+ categories go to `allowedConsentIds` and IDs of denied categories go to
297
+ `deniedConsentIds`. A visitor who turns off the `rudderstack` vendor gets every
298
+ mapped ID denied. An empty mapping, or a category with no non-blank IDs, throws.
299
+
300
+ ## Verify RudderStack
301
+
302
+ In the default mode, allowing measurement loads `rsa.min.js` with a
303
+ `data-rsa-write-key` attribute, and a page event goes to your data plane URL.
304
+
305
+ Test in a private window with an opt-in policy. Open DevTools Network, disable
306
+ the cache and filter by the vendor's domain:
307
+
308
+ 1. Load the page. No request goes to the vendor before you choose.
309
+ 2. Click Reject, then reload. There is still no vendor request.
310
+ 3. Open Privacy settings and allow the helper's category. The vendor script
311
+ loads without a page reload.
312
+ 4. Turn the category off again and save. c15t reloads the page, and the new
313
+ page makes no vendor request.
314
+
315
+ c15t reloads on revocation because removing a script element does not stop
316
+ code that already ran. The vendor's listeners, timers and queued events stay
317
+ alive until the page unloads. If you set `reloadOnConsentRevoked: false`, stop
318
+ the vendor yourself. Register a callback-only script whose `onConsentChange`
319
+ calls the vendor's opt-out API, as shown in
320
+ [custom integrations](./building-integrations.md), and check the
321
+ permission before each of your own event calls. The reload does not delete
322
+ cookies the vendor already set; see
323
+ [clear on revocation for your framework](./overview.md#vendor-switches-and-cookie-cleanup).
324
+
325
+ The helper sets `vendor` to its script ID, so once you declare that vendor a
326
+ visitor can turn it off inside an allowed category. See
327
+ [vendor consent for your framework](./overview.md#vendor-switches-and-cookie-cleanup). The
328
+ [consent verification guide](../guides/verify-consent.md) covers navigation,
329
+ expiry and hosting checks.
330
+
331
+ With `consentManagement`, the SDK loads before the choice, so check your
332
+ destinations instead. Test in a private window with an opt-in policy:
333
+
334
+ 1. Load the page. `rsa.min.js` loads before you choose. Destinations whose
335
+ consent IDs map to a denied category receive no events.
336
+ 2. Open Privacy settings and allow measurement. Without a reload,
337
+ destinations with measurement IDs start receiving events. Destinations
338
+ mapped only to marketing still receive none.
339
+ 3. Turn measurement off and save. c15t reloads the page, and destinations with
340
+ measurement IDs receive no events from the new page.
341
+
342
+ See the [consent verification guide](../guides/verify-consent.md) for
343
+ navigation and hosting checks.