@c15t/react 3.0.0-alpha.1 → 3.0.0-alpha.10

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 (406) hide show
  1. package/AGENTS.md +96 -70
  2. package/README.md +21 -17
  3. package/SKILL.md +34 -0
  4. package/dist/aggregate-components.js +1 -1
  5. package/dist/chunk-warming.js +1 -1
  6. package/dist/component-hooks/use-headless-consent-ui.js +1 -1
  7. package/dist/component-hooks/use-headless-iab-consent-ui.js +1 -1
  8. package/dist/component-hooks/use-panel-trigger.js +1 -1
  9. package/dist/components/consent-gate/atoms.js +1 -0
  10. package/dist/components/consent-gate/consent-gate.js +2 -0
  11. package/dist/components/consent-gate/frame.js +2 -0
  12. package/dist/components/consent-gate/index.js +2 -0
  13. package/dist/components/consent-preferences-link/consent-preferences-link.js +1 -1
  14. package/dist/components/iab-panel/atoms/card.js +1 -1
  15. package/dist/components/iab-panel/atoms/feature-item.js +2 -0
  16. package/dist/components/iab-panel/atoms/header.js +1 -1
  17. package/dist/components/iab-panel/atoms/purpose-item.js +1 -1
  18. package/dist/components/iab-panel/atoms/root.js +1 -1
  19. package/dist/components/iab-panel/atoms/stack-item.js +1 -1
  20. package/dist/components/iab-panel/atoms/vendor-list.js +1 -1
  21. package/dist/components/iab-panel/hooks/use-gvl-data.js +1 -1
  22. package/dist/components/iab-panel/iab-panel.js +1 -1
  23. package/dist/components/iab-panel/index.js +1 -1
  24. package/dist/components/iab-prompt/atoms/overlay.js +1 -1
  25. package/dist/components/iab-prompt/atoms/root.js +1 -1
  26. package/dist/components/panel/atoms/card.js +1 -1
  27. package/dist/components/panel/atoms/overlay.js +1 -1
  28. package/dist/components/panel/atoms/root.js +1 -1
  29. package/dist/components/panel/panel.js +1 -1
  30. package/dist/components/panel-trigger/atoms/button.js +1 -1
  31. package/dist/components/panel-trigger/atoms/icon.js +1 -1
  32. package/dist/components/panel-trigger/atoms/root.js +1 -1
  33. package/dist/components/panel-trigger/atoms/toolbar.js +1 -1
  34. package/dist/components/panel-trigger/atoms/trigger-icons.js +1 -0
  35. package/dist/components/panel-trigger/panel-trigger-toolbar.js +1 -1
  36. package/dist/components/panel-trigger/panel-trigger.js +1 -1
  37. package/dist/components/preferences/atoms/accordion.js +1 -1
  38. package/dist/components/preferences/atoms/root.js +1 -1
  39. package/dist/components/preferences/atoms/vendor-list.js +1 -0
  40. package/dist/components/preferences/index.js +1 -1
  41. package/dist/components/prompt/atoms/early-tap-script.js +2 -0
  42. package/dist/components/prompt/atoms/overlay.js +1 -1
  43. package/dist/components/prompt/atoms/root.js +1 -1
  44. package/dist/components/prompt/components.js +1 -1
  45. package/dist/components/prompt/policy-actions.js +1 -1
  46. package/dist/components/prompt/prompt.js +1 -1
  47. package/dist/components/shared/dialog-sheets.js +1 -0
  48. package/dist/components/shared/first-paint-sheets.js +1 -0
  49. package/dist/components/shared/iab-dialog-sheets.js +1 -0
  50. package/dist/components/shared/iab-first-paint-sheets.js +1 -0
  51. package/dist/components/shared/libs/compose-refs.js +1 -0
  52. package/dist/components/shared/libs/slot.js +1 -1
  53. package/dist/components/shared/primitives/button.js +1 -1
  54. package/dist/components/shared/primitives/legal-links/index.js +1 -1
  55. package/dist/components/shared/streamed-surface.js +2 -0
  56. package/dist/components/shared/surface-styles.js +2 -0
  57. package/dist/components/shared/ui/dialog/dialog.js +1 -1
  58. package/dist/components/shared/ui/icon.js +1 -1
  59. package/dist/components/shared/ui/logo.js +1 -1
  60. package/dist/components/shared/ui/preference-item/preference-item.js +1 -1
  61. package/dist/consent-gate.js +2 -0
  62. package/dist/consent-theme.js +1 -0
  63. package/dist/context/consent-tracking-context.js +1 -1
  64. package/dist/context/index.js +1 -1
  65. package/dist/context.js +1 -1
  66. package/dist/devtools-launcher.js +2 -0
  67. package/dist/devtools.js +1 -1
  68. package/dist/draft-context.js +2 -0
  69. package/dist/draft.js +1 -1
  70. package/dist/external-iab-context.js +1 -1
  71. package/dist/gpp.js +2 -0
  72. package/dist/headless.js +1 -1
  73. package/dist/hooks/use-color-scheme.js +1 -1
  74. package/dist/hooks/use-committed-ref.js +2 -0
  75. package/dist/hooks/use-focus-trap.js +1 -1
  76. package/dist/hooks/use-headless-iab-consent-ui.js +1 -1
  77. package/dist/hooks/use-iab-policy-guard.js +1 -0
  78. package/dist/hooks/use-late-entry.js +2 -0
  79. package/dist/hooks.js +1 -1
  80. package/dist/iab/styles.tw3.css +5 -45
  81. package/dist/iab-context.js +1 -1
  82. package/dist/index-parts/consent-banner.js +1 -0
  83. package/dist/index-parts/consent-dialog-link.js +1 -0
  84. package/dist/index-parts/consent-dialog-trigger.js +1 -0
  85. package/dist/index-parts/consent-dialog.js +1 -0
  86. package/dist/index-parts/consent-gate.js +1 -0
  87. package/dist/index-parts/core.js +1 -0
  88. package/dist/index-parts/draft.js +1 -0
  89. package/dist/index-parts/frame.js +1 -0
  90. package/dist/index-parts/hooks.js +1 -0
  91. package/dist/index-parts/hosted.js +1 -0
  92. package/dist/index-parts/module-hooks.js +1 -0
  93. package/dist/index-parts/offline.js +1 -0
  94. package/dist/index-parts/presets.js +1 -0
  95. package/dist/index-parts/provider.js +1 -0
  96. package/dist/index-parts/theme.js +1 -0
  97. package/dist/index-parts/translations.js +1 -0
  98. package/dist/index.js +1 -1
  99. package/dist/kernel-selector.js +1 -0
  100. package/dist/modes.js +1 -0
  101. package/dist/module-hooks/iframe-blocker.js +1 -1
  102. package/dist/module-hooks/network-blocker.js +1 -1
  103. package/dist/module-hooks/network-hold.js +2 -0
  104. package/dist/module-hooks/persistence.js +1 -1
  105. package/dist/panel-link.js +1 -1
  106. package/dist/panel-trigger.js +1 -1
  107. package/dist/panel.js +1 -1
  108. package/dist/postcss-tailwind3.js +1 -0
  109. package/dist/preferences.js +1 -2
  110. package/dist/provider.js +1 -1
  111. package/dist/server/fetch-ssr-data.js +1 -1
  112. package/dist/server/headers.js +1 -1
  113. package/dist/server/normalize-url.js +1 -1
  114. package/dist/styles.tw3.css +33 -51
  115. package/dist/transports/hosted.js +1 -0
  116. package/dist/transports/manifest.js +1 -0
  117. package/dist/transports/offline.js +1 -1
  118. package/dist/utils/deferred-module.js +2 -0
  119. package/dist/utils/merge-slot-props.js +1 -1
  120. package/dist/utils/theme-utils.js +1 -1
  121. package/dist/version.js +1 -1
  122. package/dist-types/aggregate-components.d.ts +2 -2
  123. package/dist-types/chunk-warming.d.ts +45 -8
  124. package/dist-types/component-hooks/use-headless-consent-ui.d.ts +5 -5
  125. package/dist-types/component-hooks/use-headless-iab-consent-ui.d.ts +2 -2
  126. package/dist-types/components/consent-gate/atoms.d.ts +11 -0
  127. package/dist-types/components/consent-gate/consent-gate.d.ts +2 -0
  128. package/dist-types/components/consent-gate/frame.d.ts +19 -0
  129. package/dist-types/components/consent-gate/index.d.ts +25 -0
  130. package/dist-types/components/{frame → consent-gate}/types.d.ts +7 -7
  131. package/dist-types/components/consent-preferences-link/consent-preferences-link.d.ts +1 -1
  132. package/dist-types/components/consent-preferences-link/index.d.ts +1 -1
  133. package/dist-types/components/iab-panel/atoms/feature-item.d.ts +28 -0
  134. package/dist-types/components/iab-panel/atoms/purpose-item.d.ts +5 -2
  135. package/dist-types/components/iab-panel/atoms/stack-item.d.ts +7 -2
  136. package/dist-types/components/iab-panel/atoms/vendor-list.d.ts +1 -1
  137. package/dist-types/components/iab-panel/iab-panel.d.ts +3 -3
  138. package/dist-types/components/iab-panel/index.d.ts +29 -26
  139. package/dist-types/components/iab-panel/use-iab-translations.d.ts +4 -0
  140. package/dist-types/components/iab-prompt/iab-prompt.d.ts +3 -3
  141. package/dist-types/components/iab-prompt/index.d.ts +19 -19
  142. package/dist-types/components/panel/atoms/card.d.ts +5 -4
  143. package/dist-types/components/panel/atoms/overlay.d.ts +1 -1
  144. package/dist-types/components/panel/index.d.ts +8 -8
  145. package/dist-types/components/panel/panel.d.ts +3 -3
  146. package/dist-types/components/panel-link/index.d.ts +1 -1
  147. package/dist-types/components/panel-trigger/atoms/button.d.ts +1 -1
  148. package/dist-types/components/panel-trigger/atoms/icon.d.ts +1 -1
  149. package/dist-types/components/panel-trigger/atoms/root.d.ts +2 -2
  150. package/dist-types/components/panel-trigger/atoms/toolbar.d.ts +2 -2
  151. package/dist-types/components/panel-trigger/atoms/trigger-icons.d.ts +25 -0
  152. package/dist-types/components/panel-trigger/index.d.ts +4 -4
  153. package/dist-types/components/panel-trigger/panel-trigger-toolbar.d.ts +1 -1
  154. package/dist-types/components/panel-trigger/panel-trigger.d.ts +9 -17
  155. package/dist-types/components/panel-trigger/types.d.ts +1 -1
  156. package/dist-types/components/preferences/atoms/accordion.d.ts +6 -4
  157. package/dist-types/components/preferences/atoms/button.d.ts +1 -1
  158. package/dist-types/components/preferences/atoms/footer.d.ts +1 -1
  159. package/dist-types/components/preferences/atoms/root.d.ts +1 -1
  160. package/dist-types/components/preferences/atoms/vendor-list.d.ts +23 -0
  161. package/dist-types/components/preferences/index.d.ts +14 -12
  162. package/dist-types/components/preferences/policy-actions.d.ts +2 -2
  163. package/dist-types/components/preferences/preferences.d.ts +1 -1
  164. package/dist-types/components/preferences/types.d.ts +1 -1
  165. package/dist-types/components/prompt/atoms/early-tap-script.d.ts +17 -0
  166. package/dist-types/components/prompt/atoms/root.d.ts +4 -0
  167. package/dist-types/components/prompt/components.d.ts +9 -3
  168. package/dist-types/components/prompt/index.d.ts +12 -12
  169. package/dist-types/components/prompt/policy-actions.d.ts +2 -2
  170. package/dist-types/components/prompt/prompt.d.ts +5 -1
  171. package/dist-types/components/shared/dialog-sheets.d.ts +9 -0
  172. package/dist-types/components/shared/first-paint-sheets.d.ts +8 -0
  173. package/dist-types/components/shared/iab-dialog-sheets.d.ts +3 -0
  174. package/dist-types/components/shared/iab-first-paint-sheets.d.ts +3 -0
  175. package/dist-types/components/shared/libs/compose-refs.d.ts +20 -0
  176. package/dist-types/components/shared/policy-actions.d.ts +2 -2
  177. package/dist-types/components/shared/primitives/box.d.ts +1 -1
  178. package/dist-types/components/shared/primitives/button.d.ts +2 -2
  179. package/dist-types/components/shared/primitives/button.types.d.ts +1 -1
  180. package/dist-types/components/shared/streamed-surface.d.ts +23 -0
  181. package/dist-types/components/shared/surface-styles.d.ts +36 -0
  182. package/dist-types/components/shared/ui/accordion/accordion.d.ts +2 -2
  183. package/dist-types/components/shared/ui/accordion/index.d.ts +2 -2
  184. package/dist-types/components/shared/ui/animated-collapse/index.d.ts +2 -2
  185. package/dist-types/components/shared/ui/branding.d.ts +1 -1
  186. package/dist-types/components/shared/ui/button/button.d.ts +1 -1
  187. package/dist-types/components/shared/ui/button/index.d.ts +2 -2
  188. package/dist-types/components/shared/ui/collapsible/index.d.ts +1 -1
  189. package/dist-types/components/shared/ui/dialog/index.d.ts +1 -1
  190. package/dist-types/components/shared/ui/icon.d.ts +2 -1
  191. package/dist-types/components/shared/ui/logo.d.ts +0 -10
  192. package/dist-types/components/shared/ui/preference-item/index.d.ts +1 -1
  193. package/dist-types/components/shared/ui/preference-item/preference-item.d.ts +13 -0
  194. package/dist-types/components/shared/ui/switch/index.d.ts +2 -2
  195. package/dist-types/components/shared/ui/switch/switch.d.ts +1 -1
  196. package/dist-types/components/shared/ui/tabs/index.d.ts +1 -1
  197. package/dist-types/consent-gate.d.ts +1 -0
  198. package/dist-types/consent-theme.d.ts +38 -0
  199. package/dist-types/context/consent-tracking-context.d.ts +10 -0
  200. package/dist-types/context/index.d.ts +3 -3
  201. package/dist-types/context/theme-context.d.ts +3 -3
  202. package/dist-types/context.d.ts +25 -1
  203. package/dist-types/devtools-launcher.d.ts +29 -0
  204. package/dist-types/devtools.d.ts +13 -2
  205. package/dist-types/draft-context.d.ts +31 -0
  206. package/dist-types/draft.d.ts +81 -9
  207. package/dist-types/gpp.d.ts +27 -0
  208. package/dist-types/headless.d.ts +6 -7
  209. package/dist-types/hooks/use-committed-ref.d.ts +24 -0
  210. package/dist-types/hooks/use-focus-trap.d.ts +3 -1
  211. package/dist-types/hooks/use-headless-iab-consent-ui.d.ts +1 -1
  212. package/dist-types/hooks/use-iab-manager.d.ts +5 -5
  213. package/dist-types/hooks/use-iab-policy-guard.d.ts +35 -0
  214. package/dist-types/hooks/use-late-entry.d.ts +14 -0
  215. package/dist-types/hooks/use-theme.d.ts +1 -1
  216. package/dist-types/hooks.d.ts +106 -11
  217. package/dist-types/iab.d.ts +7 -7
  218. package/dist-types/index-parts/consent-banner.d.ts +7 -0
  219. package/dist-types/index-parts/consent-dialog-link.d.ts +7 -0
  220. package/dist-types/index-parts/consent-dialog-trigger.d.ts +7 -0
  221. package/dist-types/index-parts/consent-dialog.d.ts +7 -0
  222. package/dist-types/index-parts/consent-gate.d.ts +7 -0
  223. package/dist-types/index-parts/core.d.ts +7 -0
  224. package/dist-types/index-parts/draft.d.ts +7 -0
  225. package/dist-types/index-parts/frame.d.ts +7 -0
  226. package/dist-types/index-parts/hooks.d.ts +7 -0
  227. package/dist-types/index-parts/hosted.d.ts +7 -0
  228. package/dist-types/index-parts/module-hooks.d.ts +7 -0
  229. package/dist-types/index-parts/offline.d.ts +7 -0
  230. package/dist-types/index-parts/presets.d.ts +7 -0
  231. package/dist-types/index-parts/provider.d.ts +7 -0
  232. package/dist-types/index-parts/theme.d.ts +8 -0
  233. package/dist-types/index-parts/translations.d.ts +7 -0
  234. package/dist-types/index.d.ts +32 -28
  235. package/dist-types/kernel-selector.d.ts +68 -0
  236. package/dist-types/modes.d.ts +26 -0
  237. package/dist-types/module-hooks/iframe-blocker.d.ts +33 -1
  238. package/dist-types/module-hooks/network-blocker.d.ts +23 -0
  239. package/dist-types/module-hooks/network-hold.d.ts +47 -0
  240. package/dist-types/module-hooks.d.ts +4 -4
  241. package/dist-types/panel-link.d.ts +1 -1
  242. package/dist-types/panel-trigger.d.ts +1 -1
  243. package/dist-types/panel.d.ts +13 -1
  244. package/dist-types/postcss-tailwind3.d.ts +21 -0
  245. package/dist-types/preferences.d.ts +12 -1
  246. package/dist-types/primitives/accordion.d.ts +1 -1
  247. package/dist-types/primitives/button.d.ts +1 -1
  248. package/dist-types/primitives/collapsible.d.ts +1 -1
  249. package/dist-types/primitives/dialog.d.ts +1 -1
  250. package/dist-types/primitives/preference-item.d.ts +1 -1
  251. package/dist-types/primitives/switch.d.ts +1 -1
  252. package/dist-types/primitives/tabs.d.ts +1 -1
  253. package/dist-types/primitives.d.ts +7 -7
  254. package/dist-types/prompt.d.ts +1 -1
  255. package/dist-types/provider.d.ts +169 -28
  256. package/dist-types/server/fetch-ssr-data.d.ts +1 -1
  257. package/dist-types/server/headers.d.ts +14 -4
  258. package/dist-types/server/index.d.ts +5 -5
  259. package/dist-types/server/normalize-url.d.ts +14 -7
  260. package/dist-types/server/types.d.ts +12 -1
  261. package/dist-types/theme-provider.d.ts +2 -2
  262. package/dist-types/transports/hosted.d.ts +36 -0
  263. package/dist-types/transports/manifest.d.ts +48 -0
  264. package/dist-types/transports/offline.d.ts +7 -16
  265. package/dist-types/types/index.d.ts +3 -3
  266. package/dist-types/types/manager.d.ts +1 -1
  267. package/dist-types/types/theme/index.d.ts +1 -1
  268. package/dist-types/ui-config-context.d.ts +14 -2
  269. package/dist-types/utils/deferred-module.d.ts +13 -0
  270. package/dist-types/utils/index.d.ts +4 -4
  271. package/dist-types/utils/merge-slot-props.d.ts +17 -3
  272. package/dist-types/utils/merge-styles.d.ts +1 -1
  273. package/dist-types/utils/theme-utils.d.ts +18 -3
  274. package/dist-types/version.d.ts +1 -1
  275. package/docs/README.md +96 -70
  276. package/docs/assets/v3/bottom-bar.png +0 -0
  277. package/docs/assets/v3/brand-card.png +0 -0
  278. package/docs/assets/v3/brand-preferences.png +0 -0
  279. package/docs/assets/v3/choice-wall.png +0 -0
  280. package/docs/assets/v3/headless-bar-html.png +0 -0
  281. package/docs/assets/v3/headless-bar-mobile.png +0 -0
  282. package/docs/assets/v3/headless-bar.png +0 -0
  283. package/docs/assets/v3/slim-bar.png +0 -0
  284. package/docs/concepts/choose-your-setup.md +138 -0
  285. package/docs/concepts/consent-categories.md +84 -0
  286. package/docs/concepts/consent-state.md +421 -0
  287. package/docs/concepts/data-fetching.md +270 -0
  288. package/docs/concepts/how-consent-works.md +123 -0
  289. package/docs/concepts/modes.md +278 -0
  290. package/docs/{frameworks/react/concepts/policy-presets.md → concepts/policies.md} +8 -60
  291. package/docs/customization/class-names.md +202 -0
  292. package/docs/customization/dark-mode.md +157 -0
  293. package/docs/customization/motion.md +128 -0
  294. package/docs/customization/overview.md +68 -33
  295. package/docs/customization/recipes.md +838 -47
  296. package/docs/customization/slots.md +217 -35
  297. package/docs/customization/stylesheets.md +248 -0
  298. package/docs/customization/tailwind.md +863 -0
  299. package/docs/customization/tokens.md +167 -36
  300. package/docs/customization/translations.md +87 -3
  301. package/docs/frameworks/react/callbacks.md +118 -0
  302. package/docs/frameworks/react/clear-on-revocation.md +106 -0
  303. package/docs/frameworks/react/components/consent-banner.md +48 -27
  304. package/docs/frameworks/react/components/consent-dialog-link.md +13 -11
  305. package/docs/frameworks/react/components/consent-dialog-trigger.md +86 -76
  306. package/docs/frameworks/react/components/consent-dialog.md +111 -58
  307. package/docs/frameworks/react/components/{frame.md → consent-gate.md} +70 -49
  308. package/docs/frameworks/react/components/consent-provider.md +140 -0
  309. package/docs/frameworks/react/components/consent-widget.md +69 -24
  310. package/docs/frameworks/react/components/dev-tools.md +76 -85
  311. package/docs/frameworks/react/components.md +113 -0
  312. package/docs/frameworks/react/compose.md +354 -0
  313. package/docs/frameworks/react/content-security-policy.md +143 -0
  314. package/docs/frameworks/react/customize.md +258 -0
  315. package/docs/frameworks/react/embeds.md +89 -0
  316. package/docs/frameworks/react/gpp.md +163 -0
  317. package/docs/frameworks/react/headless.md +4 -4
  318. package/docs/frameworks/react/hooks.md +70 -0
  319. package/docs/frameworks/react/iab.md +259 -0
  320. package/docs/frameworks/react/network-blocker.md +140 -0
  321. package/docs/frameworks/react/quickstart.md +220 -102
  322. package/docs/frameworks/react/rendering.md +263 -0
  323. package/docs/frameworks/react/scripts.md +114 -0
  324. package/docs/frameworks/react/translations.md +155 -0
  325. package/docs/frameworks/react/troubleshooting.md +188 -61
  326. package/docs/frameworks/react/upgrade-v3.md +651 -0
  327. package/docs/frameworks/react/vendor-consent.md +188 -0
  328. package/docs/guides/banner-experiments.md +672 -0
  329. package/docs/guides/troubleshooting.md +192 -54
  330. package/docs/guides/verify-consent.md +96 -49
  331. package/docs/integrations/adobe-analytics.md +177 -183
  332. package/docs/integrations/ahrefs-analytics.md +162 -178
  333. package/docs/integrations/amplitude.md +172 -180
  334. package/docs/integrations/building-integrations.md +137 -33
  335. package/docs/integrations/clearbit.md +164 -178
  336. package/docs/integrations/cloudflare-web-analytics.md +166 -180
  337. package/docs/integrations/cloudflare-zaraz.md +333 -0
  338. package/docs/integrations/crisp.md +174 -182
  339. package/docs/integrations/databuddy.md +167 -197
  340. package/docs/integrations/fathom-analytics.md +168 -180
  341. package/docs/integrations/front-chat.md +308 -0
  342. package/docs/integrations/google-maps.md +142 -108
  343. package/docs/integrations/google-tag-manager.md +258 -185
  344. package/docs/integrations/google-tag.md +226 -182
  345. package/docs/integrations/heap.md +173 -179
  346. package/docs/integrations/hightouch.md +171 -181
  347. package/docs/integrations/hotjar.md +169 -179
  348. package/docs/integrations/intercom.md +193 -177
  349. package/docs/integrations/klaviyo.md +473 -0
  350. package/docs/integrations/linkedin-insights.md +184 -174
  351. package/docs/integrations/logrocket.md +170 -180
  352. package/docs/integrations/matomo-analytics.md +198 -202
  353. package/docs/integrations/meta-pixel.md +198 -174
  354. package/docs/integrations/microsoft-clarity.md +173 -179
  355. package/docs/integrations/microsoft-uet.md +158 -178
  356. package/docs/integrations/mixpanel-analytics.md +165 -184
  357. package/docs/integrations/one-dollar-stats.md +292 -0
  358. package/docs/integrations/openai-pixel.md +214 -325
  359. package/docs/integrations/overview.md +152 -83
  360. package/docs/integrations/pinterest-tag.md +315 -0
  361. package/docs/integrations/pirsch.md +179 -183
  362. package/docs/integrations/plausible-analytics.md +182 -182
  363. package/docs/integrations/posthog.md +323 -264
  364. package/docs/integrations/promptwatch.md +164 -178
  365. package/docs/integrations/reddit-pixel.md +195 -181
  366. package/docs/integrations/rudderstack.md +211 -210
  367. package/docs/integrations/rybbit-analytics.md +181 -184
  368. package/docs/integrations/segment.md +192 -178
  369. package/docs/integrations/sentry.md +402 -0
  370. package/docs/integrations/snapchat-pixel.md +196 -180
  371. package/docs/integrations/tiktok-pixel.md +181 -174
  372. package/docs/integrations/umami-analytics.md +173 -182
  373. package/docs/integrations/vercel-analytics.md +176 -181
  374. package/docs/integrations/x-pixel.md +186 -174
  375. package/docs/integrations/youtube.md +150 -111
  376. package/package.json +48 -17
  377. package/dist/component-hooks/use-manager.js +0 -2
  378. package/dist/components/frame/atoms.js +0 -1
  379. package/dist/components/frame/frame.js +0 -2
  380. package/dist/components/frame/index.js +0 -2
  381. package/dist/frame.js +0 -2
  382. package/dist/ui-save.js +0 -1
  383. package/dist-types/component-hooks/use-manager.d.ts +0 -40
  384. package/dist-types/components/frame/atoms.d.ts +0 -11
  385. package/dist-types/components/frame/frame.d.ts +0 -2
  386. package/dist-types/components/frame/index.d.ts +0 -24
  387. package/dist-types/frame.d.ts +0 -1
  388. package/dist-types/ui-save.d.ts +0 -5
  389. package/docs/assets/v3/brand-bar.png +0 -0
  390. package/docs/assets/v3/mobile-card.png +0 -0
  391. package/docs/assets/v3/preferences.png +0 -0
  392. package/docs/frameworks/react/components/consent-manager-provider.md +0 -71
  393. package/docs/frameworks/react/concepts/consent-categories.md +0 -33
  394. package/docs/frameworks/react/hooks/use-consent-manager/overview.md +0 -58
  395. package/docs/frameworks/react/iab/overview.md +0 -53
  396. package/docs/frameworks/react/script-loader.md +0 -63
  397. package/docs/frameworks/react/styling/overview.md +0 -217
  398. package/docs/guides/consent-state.md +0 -60
  399. package/docs/guides/data-fetching.md +0 -163
  400. package/docs/guides/deployment-modes.md +0 -63
  401. package/docs/integrations/clear-on-revocation.md +0 -167
  402. package/docs/upgrade-v3.md +0 -334
  403. package/readme.json +0 -48
  404. package/src/iab/styles.css +0 -11
  405. package/src/styles.css +0 -10
  406. /package/dist/components/{frame → consent-gate}/types.js +0 -0
@@ -0,0 +1,258 @@
1
+ ---
2
+ title: Customize
3
+ description: Change the colors, fonts, layout, button styles and copy of the
4
+ c15t banner and dialog in a React app with theme tokens, provider options and
5
+ slots, and load the stylesheet yourself when you need to.
6
+ group: frameworks
7
+ ---
8
+
9
+ ## Pick the right tool
10
+
11
+ | Change | Use |
12
+ | ------------------------------------ | ------------------------------------------------------------------- |
13
+ | Brand colors, fonts, radius, spacing | [Theme tokens](#change-colors-fonts-and-radius) |
14
+ | Light and dark colors, animation | [Dark mode and motion](#turn-on-dark-mode-and-change-motion) |
15
+ | Which button is filled or outlined | [`consentActions`](#style-the-action-buttons) |
16
+ | Banner shape and position | [`ConsentBanner` props or `presentation`](#change-the-banner-shape) |
17
+ | One element of a component | [Component parts](#style-one-component-part) |
18
+ | Labels and languages | [Copy and translations](#change-the-copy) |
19
+ | Different markup entirely | [Headless](./headless.md) |
20
+
21
+ [Customization](../../customization/overview.md) explains how these choices relate
22
+ across frameworks.
23
+
24
+ See the [design gallery](../../customization/recipes.md) for five banner designs,
25
+ from a bottom bar to a fully custom one, with tested code for this framework.
26
+
27
+ ## Import the stylesheet yourself
28
+
29
+ A React app imports no c15t stylesheet. `ConsentBanner`, `ConsentDialog` and
30
+ the other stock components render the rules they use as `<style>` elements.
31
+
32
+ Import the stylesheet yourself with Tailwind CSS 3, to put c15t's rules in a
33
+ named cascade layer. Set `styles: false` in the provider
34
+ options, so the components add no second copy, and import the stylesheet once
35
+ in the module that renders `ConsentProvider`:
36
+
37
+ ```tsx title="src/consent.tsx (partial)"
38
+ import 'c15t/react/styles.css';
39
+
40
+ // In the ConsentProvider options:
41
+ styles: false,
42
+ ```
43
+
44
+ To import the stylesheet from CSS instead, put it at the top of your global
45
+ stylesheet, above any `@tailwind` directives. `postcss-import`, which Vite
46
+ uses, ignores an `@import` that follows other rules. Tailwind 3 also needs a
47
+ PostCSS plugin;
48
+ [Tailwind CSS](../../customization/tailwind.md#set-up-tailwind-css-3) shows the
49
+ setup.
50
+
51
+ ## Change colors, fonts and radius
52
+
53
+ Colors, radii, shadows, typography, and motion come from `--c15t-*` custom
54
+ properties. The rules the components render set the default values, as
55
+ does `styles.css` when you import it with `styles: false`. To change them,
56
+ render `ConsentTheme` with your theme where your app renders on the server,
57
+ or override the variables directly in your CSS.
58
+
59
+ `ConsentTheme` renders a `<style id="c15t-theme">` element with the
60
+ variables for `theme`. It is not a client component: rendered from a Server
61
+ Component or another server-only file, the theme generator stays out of the
62
+ browser bundle. Rendered from a client component it still works, but the
63
+ browser downloads the generator (about 1.7 KB gzip). The provider no longer
64
+ turns `theme` tokens into CSS. It still reads `consentActions` and slot
65
+ styles from its `theme` option, and warns in development when `theme` holds
66
+ tokens but the page has no `c15t-theme` stylesheet.
67
+
68
+ | `ConsentTheme` prop | Purpose |
69
+ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
70
+ | `theme` | Colors, `dark` colors, typography, spacing, radius, shadows and motion. Defaults to the built-in theme. |
71
+ | `colorScheme` | `'dark'` makes the dark tokens the default before hydration. `'system'` follows `prefers-color-scheme` with a CSS media query. Omit it to follow a `dark` or `c15t-dark` class on `<html>`. |
72
+ | `nonce` | Content Security Policy nonce for the `<style>` element. |
73
+
74
+ Pass the same `colorScheme` to `ConsentTheme` and to the provider. If your
75
+ app manages dark mode through a root class, such as next-themes' `dark`
76
+ class, omit `colorScheme` and include that class in the server HTML.
77
+ [Dark mode](../../customization/dark-mode.md) covers `theme.dark`, `null` and
78
+ a dark first paint.
79
+
80
+ To switch between different token sets at runtime, render `ConsentTheme`
81
+ from a client component and change its props, which ships the generator.
82
+
83
+ Outside a component, call `generateThemeCSS(theme, colorScheme)` from
84
+ `c15t/react/utils`, or `@c15t/react/utils` with the scoped package. It
85
+ writes the same CSS as `ConsentTheme`. Outside React, import it from
86
+ `@c15t/ui/theme`. Call it on the server or at build time and put the result in a
87
+ `<style>` element or your stylesheet. It escapes `<`, so the result is safe
88
+ inside `<style>`.
89
+
90
+ A single-page app has no server render, so pick one of two ways:
91
+
92
+ * **Set the variables in your CSS.** Nothing extra ships to the browser:
93
+
94
+ ```css title="src/index.css"
95
+ :root {
96
+ --c15t-primary: #2f6f4e;
97
+ --c15t-primary-hover: #24563c;
98
+ --c15t-text-on-primary: #fff;
99
+ --c15t-radius-lg: 4px;
100
+ }
101
+ ```
102
+
103
+ * **Render `ConsentTheme` next to the provider.** Use this when the theme lives
104
+ in TypeScript or changes at runtime. The browser downloads the theme
105
+ generator.
106
+
107
+ ```tsx title="src/consent-theme.ts"
108
+ import { defineTheme } from 'c15t/react';
109
+
110
+ export const theme = defineTheme({
111
+ colors: { primary: '#2f6f4e', primaryHover: '#24563c' },
112
+ radius: { lg: '4px' },
113
+ });
114
+ ```
115
+
116
+ In `src/consent.tsx`, render `<ConsentTheme theme={theme} />` from
117
+ `c15t/react` just before `<ConsentProvider>`.
118
+
119
+ In a server-rendered app, such as React Router framework mode, render
120
+ `ConsentTheme` in the root component so the `<style>` element is part of the
121
+ server HTML. [Theme tokens](../../customization/tokens.md) lists every variable.
122
+
123
+ `ConsentTheme` outranks a plain `:root` rule, wherever each one loads. If you
124
+ use both, a variable set in both places takes the `ConsentTheme` value. Write
125
+ your CSS overrides on `:root:root` to beat it, or move the values into the
126
+ theme.
127
+
128
+ ## Style the action buttons
129
+
130
+ `consentActions` decides how each action looks. `default` applies to every
131
+ button, `primary` to the action the policy or your props mark primary, and
132
+ `accept`, `reject`, `customize` and `dismiss` to one action each. Pass it
133
+ through the provider's `theme` option:
134
+
135
+ ```tsx title="src/consent.tsx"
136
+ <ConsentProvider
137
+ options={{
138
+ mode,
139
+ scripts,
140
+ theme: {
141
+ consentActions: {
142
+ primary: { variant: 'primary', mode: 'filled' },
143
+ dismiss: { variant: 'neutral', mode: 'stroke' },
144
+ },
145
+ },
146
+ }}
147
+ >
148
+ ```
149
+
150
+ The provider's `theme` option only reads `consentActions` and slot styles.
151
+ Tokens passed there do nothing, and the provider logs a warning in development.
152
+ Changing button styles does not change the policy or expire a saved choice.
153
+
154
+ ## Change the banner shape
155
+
156
+ `ConsentBanner` takes `variant` (`floating`, `bar`, `widget` or `wall`) and
157
+ `position`. To use one shape everywhere, set `presentation.prompt` in the
158
+ provider options instead. This banner is a full-width bar for notices and a
159
+ card for choices:
160
+
161
+ ```tsx title="src/regional-banner.tsx"
162
+ import { ConsentBanner, usePolicyRule } from 'c15t/react';
163
+
164
+ export function RegionalBanner() {
165
+ const policy = usePolicyRule();
166
+ return (
167
+ <ConsentBanner variant={policy?.prompt === 'notice' ? 'bar' : 'floating'} />
168
+ );
169
+ }
170
+ ```
171
+
172
+ Render `RegionalBanner` in place of `ConsentBanner` inside the provider.
173
+ [ConsentBanner](./components/consent-banner.md#variants)
174
+ lists every variant and position, and how to order buttons per policy.
175
+
176
+ ## Style one component part
177
+
178
+ Each component part is a slot. Set slots in the provider options under
179
+ `components`, keyed by component and part. A slot takes any attribute the
180
+ element accepts, such as `className` or `style`.
181
+
182
+ The root also carries `data-variant`, so you can restyle one shape without
183
+ touching the others. Tailwind, giving a `bar` a brand-colored top edge and
184
+ tighter text:
185
+
186
+ ```tsx
187
+ <ConsentProvider
188
+ options={{
189
+ mode,
190
+ presentation: { prompt: { variant: 'bar' } },
191
+ components: {
192
+ banner: {
193
+ root: { className: 'group' },
194
+ card: {
195
+ className:
196
+ 'group-data-[variant=bar]:border-t-4 group-data-[variant=bar]:border-t-emerald-600',
197
+ },
198
+ },
199
+ description: {
200
+ banner: { className: 'group-data-[variant=bar]:text-xs' },
201
+ },
202
+ },
203
+ }}
204
+ />
205
+ ```
206
+
207
+ `data-variant` sits on the root, so child slots use Tailwind's `group`
208
+ prefix to read it.
209
+
210
+ [Class names and CSS-in-JS](../../customization/class-names.md) shows CSS
211
+ Modules, vanilla-extract, StyleX and Emotion classes on a part.
212
+
213
+ Set `noStyle` on a component to drop the built-in classes from every part and
214
+ keep only what your slots pass. Set `noStyle` in the provider options to do it
215
+ for every component.
216
+
217
+ [Component parts](../../customization/slots.md) lists every part key under
218
+ `components` and the `data-*` attributes each part carries. Action buttons
219
+ carry `data-action`, so a single rule such as `[data-action='dismiss']`
220
+ styles one role across every surface. Right links are underlined text by
221
+ default, so the only button on a notice is the primary action.
222
+
223
+ [Component parts](../../customization/slots.md) lists every component's part keys
224
+ and when to drop the built-in styles with `noStyle`. The `ConsentGate`
225
+ placeholder's parts are `components['consent-gate'].root`, `.title` and
226
+ `.button`.
227
+ [Class names and CSS-in-JS](../../customization/class-names.md) covers CSS
228
+ Modules, vanilla-extract, StyleX and Emotion, and
229
+ [Tailwind CSS](../../customization/tailwind.md) covers utilities on parts.
230
+
231
+ ## Turn on dark mode and change motion
232
+
233
+ Pass `colorScheme` in the provider options and the same value to
234
+ `ConsentTheme`. Leave it unset to follow a `dark` class on `<html>`, and add
235
+ dark colors with `theme.dark`. [Dark mode](../../customization/dark-mode.md)
236
+ covers each value and a dark first paint.
237
+
238
+ `disableAnimation` in the provider options turns off the banner and dialog
239
+ animations, and the same prop on `ConsentBanner` or `ConsentDialog` overrides
240
+ it for one surface. [Motion and animation](../../customization/motion.md) covers
241
+ the duration and easing tokens and reduced motion.
242
+
243
+ ## Change the copy
244
+
245
+ Labels, descriptions and languages come from the translations in your Inth
246
+ project and from the provider's `i18n` option. For the visitor's language,
247
+ `i18n.messages` replace the project's copy key by key, and keys you leave out
248
+ keep the project's wording.
249
+ [Copy and translations](../../customization/translations.md) shows the message
250
+ keys. For one banner, `ConsentBanner` also accepts text props such as
251
+ `dismissButtonText`.
252
+
253
+ ## Check the result
254
+
255
+ Clear site data and reload under a policy that shows a banner. Check the banner
256
+ and the preferences dialog, since both read the same tokens. Test a narrow
257
+ window, keyboard focus and contrast on the primary button. In development, the
258
+ console warns if `theme` holds tokens but the page has no `c15t-theme` style.
@@ -0,0 +1,89 @@
1
+ ---
2
+ title: Embeds
3
+ description: Keep YouTube videos, maps and other iframes out of a React page
4
+ until their consent category is allowed, with ConsentGate or the iframe
5
+ blocker in ConsentProvider.
6
+ group: frameworks
7
+ ---
8
+
9
+ ## Pick a method
10
+
11
+ | Method | Use it when |
12
+ | ------------------ | -------------------------------------------------------------------------------------------------------- |
13
+ | `ConsentGate` | You render the iframe in a React component and want a placeholder until the visitor allows its category. |
14
+ | The iframe blocker | The iframe comes from markup you do not render with React, such as CMS or Markdown content. |
15
+
16
+ Both keep the iframe's `src` out of the page until the category is allowed, so
17
+ the embed's host receives no request before consent.
18
+
19
+ ## Gate an embed with ConsentGate
20
+
21
+ Wrap the iframe in `ConsentGate` anywhere inside `ConsentProvider`:
22
+
23
+ ```tsx title="src/video-embed.tsx"
24
+ import { ConsentDialogLink, ConsentGate } from 'c15t/react';
25
+
26
+ export const VideoEmbed = () => (
27
+ <ConsentGate
28
+ category="measurement"
29
+ placeholder={
30
+ <div className="placeholder">
31
+ <p>Allow measurement to load this YouTube video.</p>
32
+ <ConsentDialogLink>Choose video permissions</ConsentDialogLink>
33
+ </div>
34
+ }
35
+ >
36
+ <iframe
37
+ title="YouTube video"
38
+ sandbox="allow-scripts allow-same-origin allow-presentation"
39
+ src="https://www.youtube-nocookie.com/embed/czTksCF6X8Y?playsinline=1"
40
+ allow="encrypted-media; picture-in-picture"
41
+ allowFullScreen
42
+ />
43
+ </ConsentGate>
44
+ );
45
+ ```
46
+
47
+ The iframe is absent from the page until the visitor allows measurement. The
48
+ `placeholder` shows a message and a
49
+ [`ConsentDialogLink`](./components/consent-dialog-link.md)
50
+ until then. When the visitor withdraws measurement, React removes the iframe.
51
+
52
+ Pick the category that matches what the embed does. The example uses
53
+ measurement for YouTube because its player measures views. A map or chat
54
+ widget usually belongs under functionality or experience.
55
+ [ConsentGate](./components/consent-gate.md) documents the
56
+ built-in placeholder and every prop.
57
+
58
+ ## Gate an iframe with the iframe blocker
59
+
60
+ `ConsentProvider` runs the iframe blocker by default. Give an iframe
61
+ `data-src` instead of `src`, and a `data-category`:
62
+
63
+ ```html title="Markup from your CMS"
64
+ <iframe
65
+ data-src="https://www.google.com/maps/embed?pb=YOUR_EMBED_ID"
66
+ data-category="functionality"
67
+ title="Store map"
68
+ ></iframe>
69
+ ```
70
+
71
+ c15t sets `src` from `data-src` when the category is allowed and removes `src`
72
+ when the category is withdrawn. It watches the page, so iframes added later
73
+ are handled too. Add `data-vendor` with a vendor ID to also block the iframe
74
+ while the visitor has turned that vendor off.
75
+
76
+ To turn the blocker off, set `iframeBlocker: false` in the provider `options`.
77
+
78
+ ## Verify the embeds
79
+
80
+ Open the production build in a private window with DevTools open, under a
81
+ policy that asks for consent.
82
+
83
+ 1. No iframe has a `src` pointing at `youtube-nocookie.com` or
84
+ `google.com/maps`, and the Network panel shows no request to them.
85
+ 2. Allow the embed's category and save. The iframe loads.
86
+ 3. Withdraw the category and save. The page reloads without the embed.
87
+
88
+ The [YouTube](../../integrations/youtube.md) and
89
+ [Google Maps](../../integrations/google-maps.md) guides cover sizing and titles.
@@ -0,0 +1,163 @@
1
+ ---
2
+ title: IAB GPP
3
+ description: Add the IAB Global Privacy Platform API (__gpp) to a React app with
4
+ ConsentGPP from @c15t/react/gpp, so ad tech can read US state opt-outs and the
5
+ TCF EU consent string.
6
+ group: frameworks
7
+ ---
8
+
9
+ ## What GPP does
10
+
11
+ `ConsentGPP` from `@c15t/react/gpp` installs `window.__gpp`, the GPP 1.1 CMP
12
+ API, and keeps its GPP string in step with the visitor's choices. Prebid.js,
13
+ Google Ad Manager and other ad tech read US privacy signals from it.
14
+
15
+ ## Turn on GPP
16
+
17
+ Render `ConsentGPP` inside `ConsentProvider`:
18
+
19
+ ```tsx title="src/consent.tsx"
20
+ import { ConsentGPP } from '@c15t/react/gpp';
21
+
22
+ <ConsentProvider options={{ mode, scripts }}>
23
+ <ConsentGPP />
24
+ {children}
25
+ </ConsentProvider>;
26
+ ```
27
+
28
+ `ConsentGPP` renders nothing. It installs `__gpp` after it mounts and
29
+ removes it when it unmounts. It lives in its own entry, like
30
+ `@c15t/react/iab`, so apps that do not import it bundle none of the GPP
31
+ code. `@c15t/react` already depends on `@c15t/iab`; with the `c15t`
32
+ package, import from `c15t/react/gpp`.
33
+
34
+ The props are the GPP options listed below, for example
35
+ `<ConsentGPP usFallback="none" />`. It works the same with a runtime you
36
+ pass to `ConsentProvider` as `runtime`.
37
+
38
+ The GPP string follows the policy and location your backend resolves for the
39
+ visitor, so a US visitor's state comes from the backend. With `offline()`
40
+ mode, pass the state yourself, for example
41
+ `overrides: { country: 'US', region: 'CA' }`.
42
+
43
+ To add the TCF EU section for visitors under an `iab` policy, set up
44
+ [IAB TCF](./iab.md) as well.
45
+
46
+ ## How the policy decides the section
47
+
48
+ The policy rule c15t matched for the visitor decides whether a section
49
+ applies. The visitor's location only picks which US section carries it.
50
+
51
+ | Matched rule and visitor | Section in the GPP string |
52
+ | ---------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
53
+ | `iab` rule, with IAB TCF set up | `tcfeuv2` (ID 2): the TC String the CMP confirmed, unchanged |
54
+ | `iab` rule, any visitor, with `tcf: false` | None; `applicableSections` is `[-1]` |
55
+ | Any other rule with the `preferences` or `opt-out` right, US visitor in a state with a section | That state's section, such as `usca` (ID 8) |
56
+ | The same rule, US visitor whose region is unknown or whose state has no section | `usnat` (ID 7), MSPA US National version 2; none with `usFallback: 'none'` |
57
+ | The same rule, `usApproach: 'national'` | `usnat` for every US visitor |
58
+ | A rule without those rights, such as `none` | None |
59
+ | A visitor outside the US under any rule other than `iab` | None |
60
+
61
+ Every `opt-in` and `opt-out` rule has the `preferences` right, and every
62
+ `opt-out` rule also has `opt-out`. A `none` rule has them only if you add
63
+ them. A rule that gives the visitor no way to opt out produces no US
64
+ section, even when the visitor sends a GPC signal.
65
+
66
+ State sections exist for California, Colorado, Connecticut, Delaware, Florida,
67
+ Iowa, Minnesota, Montana, Nebraska, New Hampshire, New Jersey, Oregon,
68
+ Tennessee, Texas, Utah and Virginia. Indiana, Kentucky, Maryland and Rhode
69
+ Island are not encoded yet: their published specifications start the section
70
+ with a header that the IAB reference implementation does not encode. Visitors
71
+ there get the fallback, `usnat` by default. So does a US visitor whose region
72
+ the geo headers did not supply.
73
+
74
+ The MSPA US National specification describes `usnat` for MSPA signatories
75
+ that chose the national approach. Without `mspaMode`, c15t reports the
76
+ fallback as a transaction the MSPA does not cover (`MspaCoveredTransaction:
77
+ 2`), which still carries the opt-outs to vendors such as Prebid.js. If you
78
+ reserve `usnat` for the national approach, set `usFallback: 'none'`; those
79
+ visitors then get no section until their state resolves.
80
+
81
+ ## What the US sections report
82
+
83
+ * `SaleOptOut`, `SharingOptOut` and `TargetedAdvertisingOptOut`: `1` (opted
84
+ out) when the `marketing` category is not permitted, otherwise `2`. A
85
+ refusal, a GPC signal the rule maps to `marketing` through
86
+ `privacySignals.gpc`, and an opt-in rule without a grant all count.
87
+ * The opt-out notices: `1` (given), since the rule offers an opt-out.
88
+ * The sharing or processing notice: `1` when the rule has the `disclosure`
89
+ right, otherwise `2`.
90
+ * `Gpc`: the browser's Global Privacy Control signal, in sections that have a
91
+ GPC subsection. It is reported even when the rule does not map GPC to a
92
+ category, so give US rules a `privacySignals.gpc` mapping if the opt-outs
93
+ should follow it too.
94
+ * Sensitive data and known-child consents: `0` (not applicable). c15t has no
95
+ category for them, so the string states that you do not process sensitive
96
+ data or knowingly process children's data. If you do, GPP from c15t does
97
+ not describe your processing; collect and signal that consent separately.
98
+ * `MspaCoveredTransaction`: `2` (not covered) unless you set `mspaMode`.
99
+
100
+ The notice fields are your attestation, made through the rule's rights:
101
+ c15t cannot see whether your privacy notice is on the page. Show the notices
102
+ the rule promises, including a persistent opt-out control.
103
+
104
+ ## GPP options
105
+
106
+ Every field is optional. Pass them in the `gpp` option, where `gpp: true`
107
+ uses the defaults, as props on `ConsentGPP` in React, or to `mountGPP()` in
108
+ `@c15t/browser`.
109
+
110
+ | Option | Default | Effect |
111
+ | ------------------ | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
112
+ | `cmpId` | the IAB CMP ID c15t holds, else `1` | CMP ID reported by `ping`. The GPP specification has string creators without a registered ID, including MSPA US National creators, use `1`. A TCF EU section needs the registered ID its TC String names. |
113
+ | `usApproach` | `'state'` | `'state'` uses the visitor's state section. `'national'` reports `usnat` for every US visitor; the MSPA reserves it for signatories that chose the national approach. |
114
+ | `usFallback` | `'usnat'` | Under the state approach, the section for a US visitor whose state is unknown or has no section: `'usnat'` or `'none'`. |
115
+ | `mspaMode` | unset | `'opt-out-option'` or `'service-provider'`. Set it only if you signed the IAB Multi-State Privacy Agreement; the transaction is then reported as covered. In service provider mode the opt-outs are reported as not applicable. |
116
+ | `optOutCategories` | `['marketing']` | Categories whose refusal reports an opt-out of sale, sharing and targeted advertising. |
117
+ | `tcf` | `true` | Include the `tcfeuv2` section under an `iab` policy. It needs IAB TCF set up as well. |
118
+
119
+ ## Check the signal
120
+
121
+ Open the browser console on a page with GPP on and call:
122
+
123
+ ```js
124
+ __gpp('ping', (data) => console.log(data));
125
+ ```
126
+
127
+ For a California visitor who has not opted out, the result includes
128
+ `applicableSections: [8]`, `signalStatus: 'ready'` and
129
+ `parsedSections.usca[0].SaleOptOut === 2`. After the visitor refuses
130
+ `marketing`, `SaleOptOut` is `1`. `__gpp('getField', cb, 'usca.SaleOptOut')`
131
+ returns the same value. Scripts in iframes reach the API through the
132
+ `__gppLocator` frame and `postMessage`.
133
+
134
+ Under an `iab` rule, `parsedSections.tcfeuv2` uses the field names of the
135
+ IAB Europe TCF section, such as `PurposeConsent`, `VendorConsent` and
136
+ `PubRestrictions`. `getSection` and `getField` answer `null` for `tcfeuv2`,
137
+ as the IAB reference implementation does: TCF vendors read consent from
138
+ events, not on demand.
139
+
140
+ `signalStatus` stays `'not ready'` while the policy is pending, while the
141
+ banner or dialog is open, while an `iab` rule has no confirmed TC String,
142
+ and while a new TC String is decoded. Listeners added with
143
+ `addEventListener` get `signalStatus: 'not ready'`, then `cmpDisplayStatus`
144
+ and `sectionChange` events, then `signalStatus: 'ready'`.
145
+
146
+ ## Ad tags that load before c15t
147
+
148
+ c15t installs `__gpp` in the browser once consent starts, after it loads the
149
+ GPP code. Vendor scripts that call `__gpp` earlier need a stub. c15t takes over
150
+ the calls and listeners a stub queued, whether the stub keeps listeners on
151
+ `__gpp.events`, as the GPP specification's sample does, or returns them from
152
+ `__gpp('events')`, as `@iabgpp/stub` does. Call `initializeGPPStub()` from
153
+ `@c15t/iab/gpp` in your first script, or use the IAB's own stub snippet.
154
+ When another stub already answers iframes, c15t leaves that to it, so each
155
+ iframe call gets one reply.
156
+
157
+ If a CMP that has already loaded owns `__gpp`, c15t leaves it in place.
158
+ The `gpp` option reports the conflict to the `onError` callback,
159
+ `ConsentGPP` logs it, and `mountGPP()` and `createGPP()` throw. Run one GPP
160
+ CMP per page.
161
+
162
+ GPP signals what the visitor chose; it does not block scripts. Gate vendor
163
+ scripts with c15t's script loading as well.
@@ -34,13 +34,13 @@ import { useHeadlessConsentUI, useTranslations } from 'c15t/react/headless';
34
34
 
35
35
  const ACTION_LABELS = {
36
36
  accept: 'acceptAll',
37
- reject: 'rejectAll',
38
37
  customize: 'customize',
39
38
  dismiss: 'acknowledge',
39
+ reject: 'rejectAll',
40
40
  save: 'save',
41
41
  } as const;
42
42
 
43
- export function Banner() {
43
+ export const Banner = () => {
44
44
  const { banner, performAction, openDialog } = useHeadlessConsentUI();
45
45
  const { common, rights } = useTranslations();
46
46
 
@@ -49,7 +49,7 @@ export function Banner() {
49
49
  }
50
50
 
51
51
  return (
52
- <section role="region" aria-label="Privacy">
52
+ <section aria-label="Privacy">
53
53
  {banner.preferenceControls.map((right) => (
54
54
  <button key={right} type="button" onClick={openDialog}>
55
55
  {right === 'opt-out' ? rights?.optOut : rights?.preferences}
@@ -71,7 +71,7 @@ export function Banner() {
71
71
  ))}
72
72
  </section>
73
73
  );
74
- }
74
+ };
75
75
  ```
76
76
 
77
77
  `banner.actionGroups` is the resolved layout: reject and accept share a group
@@ -0,0 +1,70 @@
1
+ ---
2
+ title: Hooks
3
+ description: Gate features and save consent choices in React components with the
4
+ focused hooks exported from c15t/react.
5
+ group: frameworks
6
+ ---
7
+
8
+ ## Read only the state you need
9
+
10
+ Every hook reads the runtime from the nearest `ConsentProvider`, so call them
11
+ from components rendered inside that provider and import them from
12
+ `c15t/react`.
13
+
14
+ ```tsx title="src/optional-feature.tsx"
15
+ import { useConsent } from 'c15t/react';
16
+
17
+ export const OptionalFeature = () => {
18
+ const allowed = useConsent('marketing');
19
+ return allowed ? <div>Optional marketing content</div> : null;
20
+ };
21
+ ```
22
+
23
+ Call hooks inside the consent provider. `useConsent` reads effective permission,
24
+ which can be true under an opt-out policy without a recorded grant.
25
+
26
+ | Need | Hook |
27
+ | ----------------------------------- | ------------------------------------------ |
28
+ | One category's current permission | `useConsent(category)` |
29
+ | All current permissions | `useConsents()` |
30
+ | Recorded per-category choices | `useExplicitChoice()` |
31
+ | Whether one declared vendor may run | `useVendorAllowed(id)` |
32
+ | Whether a prompt is required | `usePromptRequirement()` |
33
+ | Active policy and resolution | `usePolicyRule()`, `usePolicyResolution()` |
34
+ | Save an explicit choice | `useSaveConsents()` |
35
+ | Open or close a consent surface | `useSetActiveUI()` |
36
+ | Acknowledge a notice | `useDismissNotice()` |
37
+
38
+ ## Save from a visitor action
39
+
40
+ Render this component inside your existing `ConsentProvider`.
41
+
42
+ ```tsx title="src/reject-button.tsx"
43
+ import { useSaveConsents } from 'c15t/react';
44
+
45
+ export const RejectButton = () => {
46
+ const save = useSaveConsents();
47
+ return (
48
+ <button
49
+ type="button"
50
+ onClick={() => {
51
+ void save('none');
52
+ }}
53
+ >
54
+ Reject optional
55
+ </button>
56
+ );
57
+ };
58
+ ```
59
+
60
+ This is an isolated action example, not a complete policy-aware banner. Use the
61
+ stock UI or headless surface actions for a complete prompt. Do not call save on
62
+ mount to persist a state derived from permissions.
63
+
64
+ Use focused hooks for feature gates. For a complete custom prompt or preference
65
+ center, use `useHeadlessConsentUI()` for surface actions and `useConsentDraft()`
66
+ for staged choices, inside one `ConsentDraftProvider` so the save commits the
67
+ same draft. v3 has no `useConsentManager()`; the
68
+ [`use-consent-manager-to-hooks` codemod](https://v3.c15t.com/docs/cli/commands/codemods#migrate-useconsentmanager-to-v3-hooks)
69
+ rewrites most of its calls to hooks. Read [how consent works](../../concepts/how-consent-works.md#a-permission-is-not-a-recorded-choice) before
70
+ treating a callback as evidence of a choice.