@c15t/react 2.0.4 → 2.2.0-canary-20260727202135

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 (332) hide show
  1. package/AGENTS.md +155 -0
  2. package/README.md +29 -14
  3. package/client/components/integrations.js +3 -0
  4. package/dist/components/consent-banner/atoms/overlay.cjs +1 -1
  5. package/dist/components/consent-banner/atoms/root.cjs +1 -1
  6. package/dist/components/consent-banner/components.cjs +1 -1
  7. package/dist/components/consent-banner/consent-banner.cjs +1 -1
  8. package/dist/components/consent-banner/error-boundary.cjs +1 -1
  9. package/dist/components/consent-banner/index.cjs +1 -1
  10. package/dist/components/consent-banner/policy-actions.cjs +1 -1
  11. package/dist/components/consent-dialog/atoms/card.cjs +1 -1
  12. package/dist/components/consent-dialog/atoms/overlay.cjs +1 -1
  13. package/dist/components/consent-dialog/atoms/root.cjs +1 -1
  14. package/dist/components/consent-dialog/consent-dialog.cjs +1 -1
  15. package/dist/components/consent-dialog/index.cjs +1 -1
  16. package/dist/components/consent-dialog-link/index.cjs +1 -1
  17. package/dist/components/consent-dialog-trigger/atoms/button.cjs +1 -1
  18. package/dist/components/consent-dialog-trigger/atoms/button.js +1 -1
  19. package/dist/components/consent-dialog-trigger/atoms/icon.cjs +1 -1
  20. package/dist/components/consent-dialog-trigger/atoms/root.cjs +1 -1
  21. package/dist/components/consent-dialog-trigger/atoms/text.cjs +1 -1
  22. package/dist/components/consent-dialog-trigger/atoms/toolbar.cjs +1 -0
  23. package/dist/components/consent-dialog-trigger/atoms/toolbar.js +1 -0
  24. package/dist/components/consent-dialog-trigger/consent-dialog-trigger-toolbar.cjs +1 -0
  25. package/dist/components/consent-dialog-trigger/consent-dialog-trigger-toolbar.js +1 -0
  26. package/dist/components/consent-dialog-trigger/consent-dialog-trigger.cjs +1 -1
  27. package/dist/components/consent-dialog-trigger/index.cjs +1 -1
  28. package/dist/components/consent-dialog-trigger/index.js +1 -1
  29. package/dist/components/consent-dialog-trigger/use-draggable.cjs +1 -1
  30. package/dist/components/consent-preferences-link/consent-preferences-link.cjs +1 -1
  31. package/dist/components/consent-preferences-link/index.cjs +1 -1
  32. package/dist/components/consent-widget/atoms/accordion.cjs +1 -1
  33. package/dist/components/consent-widget/atoms/button.cjs +1 -1
  34. package/dist/components/consent-widget/atoms/footer.cjs +1 -1
  35. package/dist/components/consent-widget/atoms/root.cjs +1 -1
  36. package/dist/components/consent-widget/consent-widget.cjs +1 -1
  37. package/dist/components/consent-widget/index.cjs +1 -1
  38. package/dist/components/consent-widget/policy-actions.cjs +1 -1
  39. package/dist/components/frame/atoms.cjs +1 -1
  40. package/dist/components/frame/atoms.js +1 -1
  41. package/dist/components/frame/frame.cjs +1 -1
  42. package/dist/components/frame/index.cjs +1 -1
  43. package/dist/components/iab-consent-banner/atoms/button-group.cjs +1 -1
  44. package/dist/components/iab-consent-banner/atoms/card.cjs +1 -1
  45. package/dist/components/iab-consent-banner/atoms/description.cjs +1 -1
  46. package/dist/components/iab-consent-banner/atoms/footer.cjs +1 -1
  47. package/dist/components/iab-consent-banner/atoms/header.cjs +1 -1
  48. package/dist/components/iab-consent-banner/atoms/overlay.cjs +1 -1
  49. package/dist/components/iab-consent-banner/atoms/root.cjs +1 -1
  50. package/dist/components/iab-consent-banner/atoms/title.cjs +1 -1
  51. package/dist/components/iab-consent-banner/iab-consent-banner.cjs +1 -1
  52. package/dist/components/iab-consent-banner/iab-consent-banner.js +1 -1
  53. package/dist/components/iab-consent-banner/index.cjs +1 -1
  54. package/dist/components/iab-consent-dialog/atoms/card.cjs +1 -1
  55. package/dist/components/iab-consent-dialog/atoms/content.cjs +1 -1
  56. package/dist/components/iab-consent-dialog/atoms/footer.cjs +1 -1
  57. package/dist/components/iab-consent-dialog/atoms/header.cjs +1 -1
  58. package/dist/components/iab-consent-dialog/atoms/overlay.cjs +1 -1
  59. package/dist/components/iab-consent-dialog/atoms/purpose-item.cjs +1 -1
  60. package/dist/components/iab-consent-dialog/atoms/root.cjs +1 -1
  61. package/dist/components/iab-consent-dialog/atoms/stack-item.cjs +1 -1
  62. package/dist/components/iab-consent-dialog/atoms/tabs.cjs +1 -1
  63. package/dist/components/iab-consent-dialog/atoms/vendor-list.cjs +1 -1
  64. package/dist/components/iab-consent-dialog/hooks/use-gvl-data.cjs +1 -1
  65. package/dist/components/iab-consent-dialog/iab-consent-dialog.cjs +1 -1
  66. package/dist/components/iab-consent-dialog/index.cjs +1 -1
  67. package/dist/components/iab-consent-dialog/use-iab-translations.cjs +1 -1
  68. package/dist/components/integrations/google-map.cjs +1 -0
  69. package/dist/components/integrations/google-map.js +1 -0
  70. package/dist/components/integrations/index.cjs +1 -0
  71. package/dist/components/integrations/index.js +1 -0
  72. package/dist/components/integrations/shared.cjs +1 -0
  73. package/dist/components/integrations/shared.js +1 -0
  74. package/dist/components/integrations/youtube-embed.cjs +1 -0
  75. package/dist/components/integrations/youtube-embed.js +1 -0
  76. package/dist/components/shared/libs/recursive-clone-children.cjs +1 -1
  77. package/dist/components/shared/libs/slot.cjs +1 -1
  78. package/dist/components/shared/libs/use-controllable-state.cjs +1 -1
  79. package/dist/components/shared/policy-actions.cjs +1 -1
  80. package/dist/components/shared/primitives/box.cjs +1 -1
  81. package/dist/components/shared/primitives/button.cjs +1 -1
  82. package/dist/components/shared/primitives/button.js +1 -1
  83. package/dist/components/shared/primitives/legal-links/index.cjs +1 -1
  84. package/dist/components/shared/primitives/legal-links/index.js +1 -1
  85. package/dist/components/shared/ui/accordion/accordion.cjs +1 -1
  86. package/dist/components/shared/ui/accordion/index.cjs +1 -1
  87. package/dist/components/shared/ui/animated-collapse/animated-collapse.cjs +1 -1
  88. package/dist/components/shared/ui/animated-collapse/index.cjs +1 -1
  89. package/dist/components/shared/ui/branding.cjs +1 -1
  90. package/dist/components/shared/ui/button/button.cjs +1 -1
  91. package/dist/components/shared/ui/button/index.cjs +1 -1
  92. package/dist/components/shared/ui/collapsible/collapsible.cjs +1 -1
  93. package/dist/components/shared/ui/collapsible/index.cjs +1 -1
  94. package/dist/components/shared/ui/dialog/dialog.cjs +1 -1
  95. package/dist/components/shared/ui/dialog/index.cjs +1 -1
  96. package/dist/components/shared/ui/icon.cjs +1 -1
  97. package/dist/components/shared/ui/logo.cjs +1 -1
  98. package/dist/components/shared/ui/preference-item/index.cjs +1 -1
  99. package/dist/components/shared/ui/preference-item/preference-item.cjs +1 -1
  100. package/dist/components/shared/ui/switch/index.cjs +1 -1
  101. package/dist/components/shared/ui/switch/switch.cjs +1 -1
  102. package/dist/components/shared/ui/tabs/index.cjs +1 -1
  103. package/dist/components/shared/ui/tabs/tabs.cjs +1 -1
  104. package/dist/context/consent-manager-context.cjs +1 -1
  105. package/dist/context/consent-tracking-context.cjs +1 -1
  106. package/dist/context/theme-context.cjs +1 -1
  107. package/dist/headless.cjs +1 -1
  108. package/dist/headless.js +1 -1
  109. package/dist/hooks/index.cjs +1 -1
  110. package/dist/hooks/index.js +1 -1
  111. package/dist/hooks/use-color-scheme.cjs +1 -1
  112. package/dist/hooks/use-component-config.cjs +1 -1
  113. package/dist/hooks/use-consent-dialog-trigger.cjs +1 -1
  114. package/dist/hooks/use-consent-manager.cjs +1 -1
  115. package/dist/hooks/use-consent-script.cjs +1 -0
  116. package/dist/hooks/use-consent-script.js +1 -0
  117. package/dist/hooks/use-focus-trap.cjs +1 -1
  118. package/dist/hooks/use-headless-consent-ui.cjs +1 -1
  119. package/dist/hooks/use-headless-iab-consent-ui.cjs +1 -1
  120. package/dist/hooks/use-reduced-motion.cjs +1 -1
  121. package/dist/hooks/use-scroll-lock.cjs +1 -1
  122. package/dist/hooks/use-ssr-status.cjs +1 -1
  123. package/dist/hooks/use-styles.cjs +1 -1
  124. package/dist/hooks/use-text-direction.cjs +1 -1
  125. package/dist/hooks/use-theme.cjs +1 -1
  126. package/dist/hooks/use-translations.cjs +1 -1
  127. package/dist/iab.cjs +1 -1
  128. package/dist/index.cjs +1 -1
  129. package/dist/index.js +1 -1
  130. package/dist/primitives/accordion.cjs +1 -1
  131. package/dist/primitives/button.cjs +1 -1
  132. package/dist/primitives/collapsible.cjs +1 -1
  133. package/dist/primitives/dialog.cjs +1 -1
  134. package/dist/primitives/preference-item.cjs +1 -1
  135. package/dist/primitives/switch.cjs +1 -1
  136. package/dist/primitives/tabs.cjs +1 -1
  137. package/dist/primitives.cjs +1 -1
  138. package/dist/providers/consent-manager-provider.cjs +1 -1
  139. package/dist/server/fetch-ssr-data.cjs +1 -1
  140. package/dist/server/fetch-ssr-data.js +1 -1
  141. package/dist/server/headers.cjs +1 -1
  142. package/dist/server/headers.js +1 -1
  143. package/dist/server/index.cjs +1 -1
  144. package/dist/server/init-cache-key.cjs +1 -1
  145. package/dist/server/normalize-url.cjs +1 -1
  146. package/dist/styles.tw3.css +1 -1
  147. package/dist/types/theme/index.cjs +1 -1
  148. package/dist/types/theme/style-types.cjs +1 -1
  149. package/dist/utils/cn.cjs +1 -1
  150. package/dist/utils/merge-styles.cjs +1 -1
  151. package/dist/utils/test-helpers.cjs +1 -1
  152. package/dist/utils/theme-utils.cjs +1 -1
  153. package/dist/version.cjs +1 -1
  154. package/dist/version.js +1 -1
  155. package/dist-types/components/consent-banner/components.d.ts +2 -2
  156. package/dist-types/components/consent-banner/policy-actions.d.ts +1 -1
  157. package/dist-types/components/consent-dialog/atoms/card.d.ts +5 -5
  158. package/dist-types/components/consent-dialog-trigger/atoms/toolbar.d.ts +22 -0
  159. package/dist-types/components/consent-dialog-trigger/consent-dialog-trigger-toolbar.d.ts +35 -0
  160. package/dist-types/components/consent-dialog-trigger/index.d.ts +2 -1
  161. package/dist-types/components/consent-dialog-trigger/types.d.ts +111 -6
  162. package/dist-types/components/consent-widget/atoms/accordion.d.ts +4 -4
  163. package/dist-types/components/consent-widget/consent-widget.d.ts +1 -1
  164. package/dist-types/components/consent-widget/policy-actions.d.ts +1 -1
  165. package/dist-types/components/integrations/google-map.d.ts +82 -0
  166. package/dist-types/components/integrations/index.d.ts +2 -0
  167. package/dist-types/components/integrations/shared.d.ts +12 -0
  168. package/dist-types/components/integrations/youtube-embed.d.ts +95 -0
  169. package/dist-types/components/shared/policy-actions.d.ts +1 -1
  170. package/dist-types/components/shared/primitives/button.d.ts +36 -2
  171. package/dist-types/components/shared/primitives/legal-links/index.d.ts +1 -1
  172. package/dist-types/components/shared/ui/accordion/accordion.d.ts +2 -2
  173. package/dist-types/components/shared/ui/branding.d.ts +3 -3
  174. package/dist-types/components/shared/ui/button/button.d.ts +1 -1
  175. package/dist-types/components/shared/ui/dialog/dialog.d.ts +1 -1
  176. package/dist-types/components/shared/ui/logo.d.ts +8 -8
  177. package/dist-types/headless.d.ts +1 -0
  178. package/dist-types/hooks/index.d.ts +1 -0
  179. package/dist-types/hooks/use-consent-script.d.ts +80 -0
  180. package/dist-types/index.d.ts +3 -1
  181. package/dist-types/providers/consent-manager-provider.d.ts +1 -1
  182. package/dist-types/server/headers.d.ts +1 -1
  183. package/dist-types/utils/theme-utils.d.ts +1 -1
  184. package/dist-types/version.d.ts +1 -1
  185. package/docs/README.md +155 -76
  186. package/docs/{building-headless-components.md → frameworks/react/building-headless-components.md} +3 -1
  187. package/docs/{callbacks.md → frameworks/react/callbacks.md} +3 -1
  188. package/docs/{components → frameworks/react/components}/consent-banner.md +10 -21
  189. package/docs/{components → frameworks/react/components}/consent-dialog-link.md +8 -5
  190. package/docs/frameworks/react/components/consent-dialog-trigger.md +202 -0
  191. package/docs/{components → frameworks/react/components}/consent-dialog.md +7 -15
  192. package/docs/frameworks/react/components/consent-manager-provider.md +228 -0
  193. package/docs/{components → frameworks/react/components}/consent-widget.md +8 -6
  194. package/docs/{components → frameworks/react/components}/dev-tools.md +9 -6
  195. package/docs/{components → frameworks/react/components}/frame.md +8 -9
  196. package/docs/{concepts → frameworks/react/concepts}/client-modes.md +4 -2
  197. package/docs/{concepts → frameworks/react/concepts}/consent-categories.md +1 -0
  198. package/docs/{concepts → frameworks/react/concepts}/consent-models.md +1 -0
  199. package/docs/{concepts → frameworks/react/concepts}/cookie-management.md +3 -3
  200. package/docs/{concepts → frameworks/react/concepts}/glossary.md +1 -0
  201. package/docs/{concepts → frameworks/react/concepts}/initialization-flow.md +1 -0
  202. package/docs/{concepts → frameworks/react/concepts}/policy-packs.md +1 -0
  203. package/docs/{headless.md → frameworks/react/headless.md} +3 -1
  204. package/docs/{hooks → frameworks/react/hooks}/use-color-scheme.md +1 -0
  205. package/docs/{hooks → frameworks/react/hooks}/use-consent-manager/checking-consent.md +3 -1
  206. package/docs/{hooks → frameworks/react/hooks}/use-consent-manager/location-info.md +3 -1
  207. package/docs/frameworks/react/hooks/use-consent-manager/overview.md +172 -0
  208. package/docs/{hooks → frameworks/react/hooks}/use-consent-manager/setting-consent.md +3 -1
  209. package/docs/{hooks → frameworks/react/hooks}/use-draggable.md +3 -1
  210. package/docs/{hooks → frameworks/react/hooks}/use-focus-trap.md +1 -0
  211. package/docs/{hooks → frameworks/react/hooks}/use-reduced-motion.md +3 -1
  212. package/docs/{hooks → frameworks/react/hooks}/use-ssr-status.md +6 -5
  213. package/docs/{hooks → frameworks/react/hooks}/use-text-direction.md +1 -0
  214. package/docs/frameworks/react/hooks/use-translations.md +55 -0
  215. package/docs/{iab → frameworks/react/iab}/consent-banner.md +9 -12
  216. package/docs/{iab → frameworks/react/iab}/consent-dialog.md +9 -14
  217. package/docs/{iab → frameworks/react/iab}/overview.md +4 -2
  218. package/docs/{iab → frameworks/react/iab}/use-gvl-data.md +3 -2
  219. package/docs/{iframe-blocking.md → frameworks/react/iframe-blocking.md} +8 -9
  220. package/docs/{internationalization.md → frameworks/react/internationalization.md} +13 -3
  221. package/docs/{network-blocker.md → frameworks/react/network-blocker.md} +13 -51
  222. package/docs/{optimization.md → frameworks/react/optimization.md} +3 -2
  223. package/docs/{policy-packs.md → frameworks/react/policy-packs.md} +3 -1
  224. package/docs/{quickstart.md → frameworks/react/quickstart.md} +26 -42
  225. package/docs/frameworks/react/script-loader.md +553 -0
  226. package/docs/{server-side.md → frameworks/react/server-side.md} +9 -4
  227. package/docs/{styling → frameworks/react/styling}/classnames.md +3 -1
  228. package/docs/{styling → frameworks/react/styling}/color-scheme.md +3 -1
  229. package/docs/frameworks/react/styling/css-variables.md +53 -0
  230. package/docs/frameworks/react/styling/overview.md +302 -0
  231. package/docs/frameworks/react/styling/slots.md +94 -0
  232. package/docs/{styling → frameworks/react/styling}/tailwind.md +3 -1
  233. package/docs/frameworks/react/styling/tokens.md +156 -0
  234. package/docs/{troubleshooting.md → frameworks/react/troubleshooting.md} +3 -1
  235. package/docs/integrations/adobe-analytics.md +160 -0
  236. package/docs/integrations/ahrefs-analytics.md +157 -0
  237. package/docs/integrations/amplitude.md +230 -0
  238. package/docs/integrations/building-integrations.md +15 -181
  239. package/docs/integrations/clearbit.md +130 -0
  240. package/docs/integrations/cloudflare-web-analytics.md +126 -0
  241. package/docs/integrations/crisp.md +140 -0
  242. package/docs/integrations/databuddy.md +152 -150
  243. package/docs/integrations/fathom-analytics.md +150 -0
  244. package/docs/integrations/google-maps.md +263 -0
  245. package/docs/integrations/google-tag-manager.md +102 -101
  246. package/docs/integrations/google-tag.md +104 -92
  247. package/docs/integrations/heap.md +219 -0
  248. package/docs/integrations/hightouch.md +199 -0
  249. package/docs/integrations/hotjar.md +143 -0
  250. package/docs/integrations/intercom.md +144 -0
  251. package/docs/integrations/linkedin-insights.md +142 -90
  252. package/docs/integrations/logrocket.md +175 -0
  253. package/docs/integrations/matomo-analytics.md +171 -0
  254. package/docs/integrations/meta-pixel.md +379 -309
  255. package/docs/integrations/microsoft-clarity.md +173 -0
  256. package/docs/integrations/microsoft-uet.md +135 -91
  257. package/docs/integrations/mixpanel-analytics.md +130 -0
  258. package/docs/integrations/overview.md +119 -75
  259. package/docs/integrations/pirsch.md +142 -0
  260. package/docs/integrations/plausible-analytics.md +154 -0
  261. package/docs/integrations/posthog.md +186 -127
  262. package/docs/integrations/promptwatch.md +121 -0
  263. package/docs/integrations/reddit-pixel.md +241 -0
  264. package/docs/integrations/rudderstack.md +271 -0
  265. package/docs/integrations/rybbit-analytics.md +143 -0
  266. package/docs/integrations/segment.md +146 -0
  267. package/docs/integrations/snapchat-pixel.md +163 -0
  268. package/docs/integrations/tiktok-pixel.md +101 -91
  269. package/docs/integrations/umami-analytics.md +148 -0
  270. package/docs/integrations/vercel-analytics.md +141 -0
  271. package/docs/integrations/x-pixel.md +123 -109
  272. package/docs/integrations/youtube.md +193 -0
  273. package/docs/shared/concepts/client-modes.md +103 -0
  274. package/docs/shared/concepts/consent-categories.md +41 -0
  275. package/docs/shared/concepts/consent-models.md +72 -0
  276. package/docs/shared/concepts/cookie-management.md +88 -0
  277. package/docs/shared/concepts/glossary.md +24 -0
  278. package/docs/shared/concepts/initialization-flow.md +105 -0
  279. package/docs/shared/concepts/policy-packs.md +225 -0
  280. package/docs/shared/react/components/consent-banner.md +242 -0
  281. package/docs/shared/react/components/consent-dialog-link.md +45 -0
  282. package/docs/shared/react/components/consent-dialog-trigger.md +185 -0
  283. package/docs/shared/react/components/consent-dialog.md +119 -0
  284. package/docs/shared/react/components/consent-manager-provider.md +183 -0
  285. package/docs/shared/react/components/consent-widget.md +121 -0
  286. package/docs/shared/react/components/dev-tools.md +81 -0
  287. package/docs/shared/react/components/frame.md +52 -0
  288. package/docs/shared/react/guides/building-headless-components.md +110 -0
  289. package/docs/shared/react/guides/callbacks.md +89 -0
  290. package/docs/shared/react/guides/headless.md +31 -0
  291. package/docs/shared/react/guides/iframe-blocking.md +65 -0
  292. package/docs/shared/react/guides/internationalization.md +123 -0
  293. package/docs/shared/react/guides/network-blocker.md +72 -0
  294. package/docs/shared/react/guides/optimization.md +44 -0
  295. package/docs/shared/react/guides/policy-packs.md +173 -0
  296. package/docs/shared/react/guides/script-loader.md +309 -0
  297. package/docs/shared/react/hooks/use-color-scheme.md +31 -0
  298. package/docs/shared/react/hooks/use-consent-manager/checking-consent.md +95 -0
  299. package/docs/shared/react/hooks/use-consent-manager/location-info.md +96 -0
  300. package/docs/shared/react/hooks/use-consent-manager/overview.md +74 -0
  301. package/docs/shared/react/hooks/use-consent-manager/setting-consent.md +93 -0
  302. package/docs/shared/react/hooks/use-draggable.md +30 -0
  303. package/docs/shared/react/hooks/use-focus-trap.md +20 -0
  304. package/docs/shared/react/hooks/use-reduced-motion.md +33 -0
  305. package/docs/shared/react/hooks/use-ssr-status.md +16 -0
  306. package/docs/shared/react/hooks/use-text-direction.md +38 -0
  307. package/docs/shared/react/hooks/use-translations.md +15 -0
  308. package/docs/shared/react/iab/consent-banner.md +60 -0
  309. package/docs/shared/react/iab/consent-dialog.md +76 -0
  310. package/docs/shared/react/iab/overview.md +80 -0
  311. package/docs/shared/react/iab/use-gvl-data.md +21 -0
  312. package/docs/shared/react/styling/classnames.md +93 -0
  313. package/docs/shared/react/styling/color-scheme.md +35 -0
  314. package/docs/shared/react/styling/css-variables.md +53 -0
  315. package/docs/shared/react/styling/overview.md +261 -0
  316. package/docs/shared/react/styling/slots.md +93 -0
  317. package/docs/shared/react/styling/stylesheet-entrypoint.md +8 -0
  318. package/docs/shared/react/styling/tailwind.md +88 -0
  319. package/docs/shared/react/styling/tokens.md +155 -0
  320. package/docs/shared/troubleshooting.md +82 -0
  321. package/package.json +23 -12
  322. package/readme.json +12 -7
  323. package/docs/ai-agents.md +0 -111
  324. package/docs/components/consent-dialog-trigger.md +0 -103
  325. package/docs/components/consent-manager-provider.md +0 -425
  326. package/docs/hooks/use-consent-manager/overview.md +0 -420
  327. package/docs/hooks/use-translations.md +0 -118
  328. package/docs/script-loader.md +0 -321
  329. package/docs/styling/css-variables.md +0 -92
  330. package/docs/styling/overview.md +0 -460
  331. package/docs/styling/slots.md +0 -128
  332. package/docs/styling/tokens.md +0 -216
@@ -0,0 +1,89 @@
1
+ ---
2
+ title: Callbacks
3
+ description: Reference page for callbacks.
4
+ group: reference
5
+ ---
6
+ Callbacks let you run custom code at key points in the consent lifecycle. Define them in the provider or runtime `callbacks` option, or register them dynamically after initialization.
7
+
8
+ For analytics SDKs and other change-only integrations, prefer `subscribeToConsentChanges()` or `onConsentChanged`. Use `onConsentSet` when you want the broader lifecycle signal, including initialization, automatic defaults, and replay-aware registration.
9
+
10
+ ## Choose the Right Surface
11
+
12
+ |Surface|Replays when registered late?|Fires on init / hydration / auto-grants?|Best for|
13
+ |--|--|--|--|
14
+ |`onBannerFetched`|Yes, via `setCallback('onBannerFetched', ...)` after init|Yes|Logging resolved policy, location, and translations|
15
+ |`onConsentSet`|Yes, via `setCallback('onConsentSet', ...)`|Yes|Broad lifecycle hooks, debugging, and integrations that want the latest full state regardless of how it was reached|
16
+ |`onConsentChanged`|No|No|Declarative change-only integrations|
17
+ |`subscribeToConsentChanges()`|No|No|Canonical change-only subscriptions after mount|
18
+
19
+ > ℹ️ **Info:**
20
+ > Script.onConsentChange is a script-scoped lifecycle hook. It is not the global consent change API for analytics SDKs or other app-wide integrations.
21
+
22
+ ## Available Callbacks
23
+
24
+ ### `onBannerFetched`
25
+
26
+ Called when the consent banner data is fetched from the backend (or loaded from SSR data). The payload includes jurisdiction info, location data, and resolved translations.
27
+
28
+ ```tsx
29
+ onBannerFetched: ({ jurisdiction, location, translations }) => {
30
+ // jurisdiction: 'GDPR' | 'CCPA' | { code: 'GDPR', message: '...' } | ...
31
+ // location: { countryCode: 'DE', regionCode: 'BY' }
32
+ // translations: { language: 'de', translations: {...} }
33
+ }
34
+ ```
35
+
36
+ ### `onConsentSet`
37
+
38
+ Called whenever c15t broadly settles consent state: store initialization, automatic defaults during init, explicit saves, and replay via `setCallback('onConsentSet', ...)`.
39
+
40
+ ```tsx
41
+ onConsentSet: ({ preferences }) => {
42
+ // preferences: { necessary: true, measurement: true, marketing: false, ... }
43
+ console.log('Latest consent state:', preferences);
44
+ }
45
+ ```
46
+
47
+ ### `onConsentChanged`
48
+
49
+ Called only after an explicit `saveConsents()` or `setConsent()` that actually changes the saved consent state. It never fires on store creation, hydration, automatic grants, unchanged saves, or `setCallback('onConsentChanged', ...)`.
50
+
51
+ ```tsx
52
+ onConsentChanged: ({
53
+ preferences,
54
+ previousPreferences,
55
+ allowedCategories,
56
+ deniedCategories,
57
+ previousAllowedCategories,
58
+ previousDeniedCategories,
59
+ }) => {
60
+ analytics.syncConsent({
61
+ allowedCategories,
62
+ deniedCategories,
63
+ previousAllowedCategories,
64
+ previousDeniedCategories,
65
+ });
66
+ }
67
+ ```
68
+
69
+ ### `onError`
70
+
71
+ Called when an error occurs during consent operations (e.g., API request failure). If no `onError` callback is provided, errors are logged to `console.error`.
72
+
73
+ ```tsx
74
+ onError: ({ error }) => {
75
+ // error: string describing what went wrong
76
+ Sentry.captureMessage(`Consent error: ${error}`);
77
+ }
78
+ ```
79
+
80
+ ### `onBeforeConsentRevocationReload`
81
+
82
+ Called synchronously before the page reloads due to consent revocation. This is your last chance to run cleanup before the reload. Keep this callback fast - avoid async operations.
83
+
84
+ ```tsx
85
+ onBeforeConsentRevocationReload: ({ preferences }) => {
86
+ // Flush any pending data
87
+ navigator.sendBeacon('/api/flush', JSON.stringify({ session: sessionId }));
88
+ }
89
+ ```
@@ -0,0 +1,31 @@
1
+ ---
2
+ title: Headless
3
+ description: Reference page for headless.
4
+ group: reference
5
+ ---
6
+ c15t's headless mode means using the hooks (`useConsentManager`, `useTranslations`, etc.) without any pre-built UI components. This gives you complete control over the consent experience.
7
+
8
+ Before you go headless, walk the customization ladder in order:
9
+
10
+ 1. **Pre-built components** - Use provider options, component props, tokens, slots, and `theme.consentActions`
11
+ 2. **Compound components** - Rearrange c15t primitives when the markup order must change
12
+ 3. **`noStyle`** - Keep c15t structure but replace its styling
13
+ 4. **Headless** - Use only hooks and build the entire UI yourself
14
+
15
+ ## When to Go Headless
16
+
17
+ Go headless when:
18
+
19
+ * Your design system requires complete control over markup
20
+ * You need a consent flow that doesn't fit the banner/dialog pattern
21
+ * You want to embed consent choices inline rather than as overlays
22
+
23
+ Use a lower-power tool instead when:
24
+
25
+ * The component structure works but the styling doesn't -> use tokens, slots, or `noStyle`
26
+ * You only need to rearrange existing c15t parts -> use compound components
27
+ * You want to change copy -> use `ConsentManagerProvider.options.i18n`
28
+ * You only need to restyle stock actions -> use `theme.consentActions`
29
+
30
+ > ⚠️ **Warning:**
31
+ > Headless mode is not the first answer for pure theming. If you are still trying to debug why a banner footer color did not change, stay in the styling system and verify the token-to-component mapping before you rebuild the UI.
@@ -0,0 +1,65 @@
1
+ ---
2
+ title: Iframe Blocking
3
+ description: Reference page for iframe blocking.
4
+ group: reference
5
+ ---
6
+ Embedded iframes from third parties (YouTube, Google Maps, social media widgets) can set cookies and track users without their consent. c15t provides two approaches to gate iframes behind consent:
7
+
8
+ 1. **`<Frame>` component** - A React component that conditionally renders children based on consent
9
+ 2. **HTML `data-category` attribute** - For raw `<iframe>` elements outside of React
10
+
11
+ ### Custom Placeholder
12
+
13
+ Replace the default placeholder with your own UI:
14
+
15
+ ```tsx
16
+ <Frame
17
+ category="marketing"
18
+ placeholder={
19
+ <div className="flex items-center justify-center h-64 bg-gray-100 rounded">
20
+ <p>Enable marketing cookies to watch this video.</p>
21
+ </div>
22
+ }
23
+ >
24
+ <iframe src="https://www.youtube.com/embed/..." />
25
+ </Frame>
26
+ ```
27
+
28
+ ### Compound Components
29
+
30
+ Build custom placeholder layouts using compound components:
31
+
32
+ ```tsx
33
+ <Frame.Root category="marketing">
34
+ <Frame.Title category="marketing" />
35
+ <Frame.Button category="marketing" />
36
+ </Frame.Root>
37
+ ```
38
+
39
+ ## HTML Attribute Approach
40
+
41
+ For iframes outside of React (e.g., CMS content, server-rendered HTML), add `data-category` and use `data-src` instead of `src`:
42
+
43
+ ```html
44
+ <iframe
45
+ data-src="https://www.youtube.com/embed/dQw4w9WgXcQ"
46
+ data-category="marketing"
47
+ width="560"
48
+ height="315"
49
+ ></iframe>
50
+ ```
51
+
52
+ When consent for the specified category is granted, c15t automatically swaps `data-src` to `src`, loading the iframe. When consent is revoked, `src` is moved back to `data-src`.
53
+
54
+ ### Dynamic Iframes
55
+
56
+ c15t uses a `MutationObserver` to watch for dynamically added iframes. Any iframe with `data-category` added to the DOM after initialization is automatically processed.
57
+
58
+ ## API Reference
59
+
60
+ |Property|Value|
61
+ |:--|:--|
62
+ |Type Name|\`FrameProps\`|
63
+ |Source Path|\`./packages/react/src/components/frame/types.ts\`|
64
+
65
+ \*ExtractedTypeTable: Could not extract "FrameProps" from "./packages/react/src/components/frame/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
@@ -0,0 +1,123 @@
1
+ ---
2
+ title: Internationalization
3
+ description: Reference page for internationalization.
4
+ group: reference
5
+ ---
6
+ c15t ships with built-in translations for 30+ languages via the `@c15t/translations` package. Language detection happens automatically based on the browser's language preference, and you can override or extend translations for any language.
7
+
8
+ In c15t v2, the preferred config shape is `i18n` with `locale`, `detectBrowserLanguage`, and `messages`.
9
+
10
+ There are two ways c15t can load translations: client-side or server-side.
11
+
12
+ |Server-side|Client-side|
13
+ |--|--|
14
+ |The best way to reduce bundle size and improve performance. We can detect the user's language based on the browser's language settings, allowing for the most accurate translations. By default, when using a [inth.com](https://inth.com) hosted instance, [these languages](https://github.com/c15t/c15t/tree/main/packages/translations/src/translations) are supported.|Bundled with the application allowing for multiple languages to be supported without the need for a backend. The more translations you have, the larger the bundle size will be, which may impact the performance of your application.|
15
+
16
+ ## Translation Package Imports
17
+
18
+ Use the import path that matches your use case:
19
+
20
+ * `@c15t/translations`: types, utilities, and `enTranslations` only (smallest client bundle)
21
+ * `@c15t/translations/en`: English-only translation object
22
+ * `@c15t/translations/all`: full `baseTranslations` map for all bundled locales
23
+
24
+ If you bundle translations client-side and need multiple languages, import from `@c15t/translations/all` explicitly:
25
+
26
+ ```tsx
27
+ import { baseTranslations } from '@c15t/translations/all';
28
+
29
+ const translations = {
30
+ en: baseTranslations.en,
31
+ de: baseTranslations.de,
32
+ fr: baseTranslations.fr,
33
+ };
34
+ ```
35
+
36
+ ## Translation Sections
37
+
38
+ The `Translations` object is organized into sections:
39
+
40
+ |Section|Controls|
41
+ |--|--|
42
+ |`common`|Shared button labels: acceptAll, rejectAll, customize, save|
43
+ |`cookieBanner`|Banner title and description|
44
+ |`consentManagerDialog`|Dialog title and description|
45
+ |`consentTypes`|Per-category title and description (keyed by AllConsentNames)|
46
+ |`frame`|Frame placeholder title, button, loading, and error text (title and button support `{category}`)|
47
+ |`legalLinks`|Privacy policy, cookie policy, terms of service link text|
48
+ |`iab`|IAB TCF banner, preference center, vendor list translations|
49
+
50
+ ## Automatic Language Detection
51
+
52
+ By default, c15t detects the browser's language (`navigator.language`) and selects the closest matching translation. If custom `messages` are configured, fallback stays within your configured languages before using `locale` (or `'en'`) as the preferred fallback language.
53
+
54
+ When backend policy packs use `i18n.messageProfile`, the active language pool comes only from that resolved profile.
55
+
56
+ Example: if your Europe profile defines `en`, `fr`, and `de`, and your default profile defines `en`, `es`, and `pt`, a Europe visitor can resolve to `en`, `fr`, or `de`, but not `es`, `pt`, or `zh`.
57
+
58
+ Use profile-local `fallbackLanguage` inside backend `i18n.messages` to choose which configured language a policy profile should fall back to when the browser asks for an unsupported locale.
59
+
60
+ Disable auto-detection to always use `locale`:
61
+
62
+ ```tsx
63
+ i18n: {
64
+ locale: 'de',
65
+ detectBrowserLanguage: false,
66
+ messages: { ... },
67
+ }
68
+ ```
69
+
70
+ If you need a policy to always use one specific language regardless of browser preference, set `policy.i18n.language` on the backend policy pack.
71
+
72
+ ## Custom Consent Type Labels
73
+
74
+ Override the title and description for individual consent categories. Frame
75
+ placeholders use that title anywhere their message contains `{category}`, so
76
+ the title and action stay consistent:
77
+
78
+ ```tsx
79
+ i18n: {
80
+ messages: {
81
+ en: {
82
+ consentTypes: {
83
+ measurement: {
84
+ title: 'Analytics & Performance',
85
+ description: 'Help us understand how visitors interact with our site.',
86
+ },
87
+ marketing: {
88
+ title: 'Advertising',
89
+ description: 'Used to deliver relevant ads and measure campaign effectiveness.',
90
+ },
91
+ },
92
+ frame: {
93
+ title: 'Allow {category} consent to view this content.',
94
+ actionButton: 'Enable {category} consent',
95
+ loading: 'Loading content…',
96
+ error: 'This content could not be loaded.',
97
+ },
98
+ },
99
+ },
100
+ }
101
+ ```
102
+
103
+ ## Legacy `translations` Compatibility
104
+
105
+ The legacy syntax is still supported in 2.0 for RC compatibility:
106
+
107
+ ```tsx
108
+ // Legacy (still supported)
109
+ translations: {
110
+ defaultLanguage: 'en',
111
+ disableAutoLanguageSwitch: true,
112
+ translations: { ... },
113
+ }
114
+
115
+ // Preferred in v2
116
+ i18n: {
117
+ locale: 'en',
118
+ detectBrowserLanguage: false,
119
+ messages: { ... },
120
+ }
121
+ ```
122
+
123
+ If both are provided, `i18n` takes precedence.
@@ -0,0 +1,72 @@
1
+ ---
2
+ title: Network Blocker
3
+ description: Reference page for network blocker.
4
+ group: reference
5
+ ---
6
+ The network blocker intercepts outgoing `fetch` and `XMLHttpRequest` calls and blocks them based on consent state and domain rules. This catches tracking requests that happen outside of script loading - for example, beacon calls, API requests to analytics endpoints, or pixel fires from already-loaded scripts.
7
+
8
+ ## Rule Matching
9
+
10
+ Rules match requests using three criteria:
11
+
12
+ ### Domain matching
13
+
14
+ The `domain` field matches the request hostname. Subdomains are automatically included - a rule for `google-analytics.com` also matches `www.google-analytics.com` and `stats.google-analytics.com`.
15
+
16
+ ### Path matching
17
+
18
+ The optional `pathIncludes` field requires the request URL path to contain the specified substring. This lets you target specific endpoints without blocking the entire domain.
19
+
20
+ ### Method matching
21
+
22
+ The optional `methods` array restricts the rule to specific HTTP methods. If omitted, the rule applies to all methods.
23
+
24
+ ## Consent Conditions
25
+
26
+ Like the script loader, `category` accepts a `HasCondition`:
27
+
28
+ ```tsx
29
+ // Simple
30
+ { category: 'measurement' }
31
+
32
+ // Must have both
33
+ { category: { and: ['measurement', 'marketing'] } }
34
+
35
+ // Must have either
36
+ { category: { or: ['measurement', 'marketing'] } }
37
+ ```
38
+
39
+ ## Monitoring Blocked Requests
40
+
41
+ ### Console logging
42
+
43
+ Blocked requests are logged to the console by default. Disable with `logBlockedRequests: false`.
44
+
45
+ ### Callback
46
+
47
+ Use `onRequestBlocked` to handle blocked requests programmatically:
48
+
49
+ ```tsx
50
+ networkBlocker: {
51
+ rules: [...],
52
+ onRequestBlocked: ({ method, url, rule }) => {
53
+ console.log(`Blocked ${method} ${url} (rule: ${rule?.id})`);
54
+ },
55
+ }
56
+ ```
57
+
58
+ ## API Reference
59
+
60
+ |Property|Value|
61
+ |:--|:--|
62
+ |Type Name|\`NetworkBlockerRule\`|
63
+ |Source Path|\`./packages/core/src/libs/network-blocker/types.ts\`|
64
+
65
+ \*ExtractedTypeTable: Could not extract "NetworkBlockerRule" from "./packages/core/src/libs/network-blocker/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
66
+
67
+ |Property|Value|
68
+ |:--|:--|
69
+ |Type Name|\`NetworkBlockerConfig\`|
70
+ |Source Path|\`./packages/core/src/libs/network-blocker/types.ts\`|
71
+
72
+ \*ExtractedTypeTable: Could not extract "NetworkBlockerConfig" from "./packages/core/src/libs/network-blocker/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
@@ -0,0 +1,44 @@
1
+ ---
2
+ title: Optimization
3
+ description: Reference page for optimization.
4
+ group: reference
5
+ ---
6
+ Use this guide when you care about banner visibility speed, route static-ness, and reducing backend round-trip cost.
7
+
8
+ Why this helps:
9
+
10
+ * Same-origin requests avoid extra DNS/TLS setup in many deployments
11
+ * Ad blockers are less likely to block your init endpoint
12
+ * You can change backend infrastructure without touching client code
13
+
14
+ In production benchmarks with a same-origin rewrite, prefetching strategies show measurable improvement over client-only init:
15
+
16
+ |Strategy|Scripts loaded|Data request starts|Banner visible|
17
+ |--|--|--|--|
18
+ |Client-only (no prefetch)|baseline|baseline|baseline|
19
+ |Browser prefetch|\~1.3x faster|\~2.6x earlier|\~1.25x faster|
20
+ |Server prefetch|\~2x faster|before page loads|\~1.9x faster|
21
+
22
+ ## Keep The Provider Mounted Across Navigation
23
+
24
+ Mount the consent provider at the app root so route transitions do not remount it.
25
+
26
+ Why this helps:
27
+
28
+ * Avoids re-running init work on client-side navigation
29
+ * Prevents extra callback churn from remount cycles
30
+ * Keeps banner/dialog state stable between route transitions
31
+
32
+ ## Animation Performance
33
+
34
+ The default motion tokens are tuned for speed-first product UI:
35
+
36
+ |Token|Duration|Used for|
37
+ |--|--|--|
38
+ |`fast`|80ms|Banner slide + overlay, card scale, button hover, widget entry/exit|
39
+ |`normal`|150ms|Accordion, switch toggle|
40
+ |`slow`|200ms|Dialog trigger snap, tab indicator|
41
+
42
+ These defaults follow the principle that product UI should be fast and purposeful — animations exist for spatial continuity, not decoration. In benchmarks, animation duration contributes a constant floor to "data fetched → banner visible" timing. The default tokens sit at the lower end of standard UI ranges (80-200ms) to minimize that floor.
43
+
44
+ If you must use a cross-origin backend URL, add preconnect so the browser starts DNS/TLS early:
@@ -0,0 +1,173 @@
1
+ ---
2
+ title: Policy Packs
3
+ description: Reference page for policy packs.
4
+ group: reference
5
+ ---
6
+ Policy packs configure how c15t handles regional consent — which model (opt-in, opt-out, none), which categories, and what UI to show. The backend resolves the right policy automatically based on the visitor's location.
7
+
8
+ **For most apps, you just need a `ConsentManagerProvider` pointing at your backend with presets configured there.** The frontend receives the resolved policy via the `/init` response — no client-side policy config required.
9
+
10
+ When a backend isn't available — local development, static previews, Storybook, automated tests, or as a resilience fallback during a temporary outage — you can pass policies directly to the provider via `offlinePolicy.policyPacks` and c15t resolves them locally.
11
+
12
+ > ℹ️ **Info:**
13
+ > For QA and testing, use the c15t DevTools to simulate different regions and policy responses against your real backend, rather than switching to offline mode.
14
+
15
+ ## Hosted Mode (Recommended)
16
+
17
+ When using inth.com or a self-hosted backend, the provider connects automatically. No policy configuration is needed on the frontend:
18
+
19
+ ```tsx
20
+ <ConsentManagerProvider
21
+ options={{
22
+ backendURL: 'https://your-instance.c15t.dev',
23
+ }}
24
+ >
25
+ <ConsentBanner />
26
+ <ConsentDialog />
27
+ {children}
28
+ </ConsentManagerProvider>
29
+ ```
30
+
31
+ The backend resolves the correct policy based on the visitor's geo data and returns it in the `/init` response. Configure your presets on the backend side.
32
+
33
+ ## Offline Presets (Development and Fallback)
34
+
35
+ Use offline presets mainly for local development, Storybook, deterministic tests, or temporary backend outages:
36
+
37
+ ```tsx
38
+ import { policyPackPresets } from '@c15t/react';
39
+
40
+ offlinePolicy: {
41
+ i18n: {
42
+ defaultProfile: 'default',
43
+ messages: {
44
+ default: {
45
+ translations: {
46
+ en: { cookieBanner: { title: 'Privacy choices' } },
47
+ },
48
+ },
49
+ eu: {
50
+ fallbackLanguage: 'en',
51
+ translations: {
52
+ en: { cookieBanner: { title: 'EU GDPR Consent' } },
53
+ fr: { cookieBanner: { title: 'Consentement RGPD' } },
54
+ de: { cookieBanner: { title: 'GDPR-Einwilligung' } },
55
+ },
56
+ },
57
+ },
58
+ },
59
+ policyPacks: [
60
+ {
61
+ ...policyPackPresets.europeOptIn(),
62
+ i18n: { messageProfile: 'eu' },
63
+ },
64
+ policyPackPresets.californiaOptOut(),
65
+ policyPackPresets.worldNoBanner(),
66
+ ],
67
+ }
68
+ ```
69
+
70
+ Available presets:
71
+
72
+ |Preset|Model|Matches|
73
+ |--|--|--|
74
+ |`europeOptIn()`|`opt-in`|EEA + UK countries + geo fallback|
75
+ |`europeIab()`|`iab`|EEA + UK countries + geo fallback (TCF 2.3)|
76
+ |`californiaOptOut()`|`opt-out`|US-CA region|
77
+ |`quebecOptIn()`|`opt-in`|CA-QC region|
78
+ |`worldNoBanner()`|`none`|default fallback|
79
+
80
+ ## Provider Shape
81
+
82
+ Configure packs through `offlinePolicy.policyPacks`. Add `offlinePolicy.i18n`
83
+ when you want local previews or fallback behavior to mirror hosted policy-profile language behavior:
84
+
85
+ ```tsx
86
+ <ConsentManagerProvider
87
+ options={{
88
+ mode: 'offline',
89
+ offlinePolicy: {
90
+ i18n: {
91
+ defaultProfile: 'default',
92
+ messages: {
93
+ default: {
94
+ translations: {
95
+ en: { cookieBanner: { title: 'Privacy choices' } },
96
+ },
97
+ },
98
+ qc: {
99
+ fallbackLanguage: 'fr',
100
+ translations: {
101
+ en: { cookieBanner: { title: 'Quebec Privacy Settings' } },
102
+ fr: { cookieBanner: { title: 'Paramètres de confidentialité du Québec' } },
103
+ },
104
+ },
105
+ },
106
+ },
107
+ policyPacks: [
108
+ {
109
+ id: 'qc_opt_in',
110
+ match: { regions: [{ country: 'CA', region: 'QC' }] },
111
+ i18n: { messageProfile: 'qc' },
112
+ consent: { model: 'opt-in', expiryDays: 365 },
113
+ ui: { mode: 'banner' },
114
+ },
115
+ {
116
+ id: 'default',
117
+ match: { isDefault: true },
118
+ consent: { model: 'none' },
119
+ ui: { mode: 'none' },
120
+ },
121
+ ],
122
+ },
123
+ overrides: { country: 'CA', region: 'QC' },
124
+ }}
125
+ >
126
+ ```
127
+
128
+ With that setup, offline mode resolves language the same way as hosted mode:
129
+
130
+ * the active policy profile defines the allowed language set
131
+ * each profile can define its own `fallbackLanguage`
132
+ * built-in translations only fill missing keys for the selected language
133
+
134
+ ## Fallback Behavior
135
+
136
+ |Configuration|Result|
137
+ |--|--|
138
+ |`offlinePolicy.policyPacks` omitted|Synthetic opt-in fallback banner (also used for hosted network fallback)|
139
+ |`offlinePolicy: { policyPacks: [] }`|Explicit no-banner mode|
140
+ |Non-empty pack, no match, no default|Explicit no-banner mode|
141
+
142
+ Omitting the option gives you a safe opt-in default for local development and outage scenarios. Providing it tells c15t you want deterministic preview or fallback behavior exactly as configured.
143
+
144
+ ## QA and Debugging
145
+
146
+ The best way to test regional consent behavior is with the [c15t DevTools](/docs/frameworks/react/dev-tools). The DevTools Policy panel lets you simulate different countries, regions, and GPC signals against your real backend — no code changes needed.
147
+
148
+ For deeper inspection:
149
+
150
+ * Read `policy` and `policyDecision` from `useConsentManager()` to see the resolved config
151
+ * Open the DevTools Policy panel to inspect matcher resolution and fingerprints
152
+ * Compare your frontend preview with the backend `/init` response before shipping
153
+
154
+ If you need fully deterministic resolution without a backend during testing or preview work (for example, in automated tests or Storybook), pair `offlinePolicy.policyPacks` with `overrides`:
155
+
156
+ ```tsx
157
+ options={{
158
+ mode: 'offline',
159
+ offlinePolicy: {
160
+ policyPacks: [
161
+ policyPackPresets.europeOptIn(),
162
+ policyPackPresets.californiaOptOut(),
163
+ policyPackPresets.worldNoBanner(),
164
+ ],
165
+ },
166
+ overrides: {
167
+ country: 'US',
168
+ region: 'CA',
169
+ language: 'en-US',
170
+ gpc: true, // Simulate Global Privacy Control
171
+ },
172
+ }}
173
+ ```