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

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 (413) hide show
  1. package/AGENTS.md +97 -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/iab-prompt/iab-prompt.js +1 -1
  27. package/dist/components/panel/atoms/card.js +1 -1
  28. package/dist/components/panel/atoms/overlay.js +1 -1
  29. package/dist/components/panel/atoms/root.js +1 -1
  30. package/dist/components/panel/panel.js +1 -1
  31. package/dist/components/panel-trigger/atoms/button.js +1 -1
  32. package/dist/components/panel-trigger/atoms/icon.js +1 -1
  33. package/dist/components/panel-trigger/atoms/root.js +1 -1
  34. package/dist/components/panel-trigger/atoms/toolbar.js +1 -1
  35. package/dist/components/panel-trigger/atoms/trigger-icons.js +1 -0
  36. package/dist/components/panel-trigger/panel-trigger-toolbar.js +1 -1
  37. package/dist/components/panel-trigger/panel-trigger.js +1 -1
  38. package/dist/components/panel-trigger/toolbar-loader.js +2 -0
  39. package/dist/components/preferences/atoms/accordion.js +1 -1
  40. package/dist/components/preferences/atoms/root.js +1 -1
  41. package/dist/components/preferences/atoms/vendor-list.js +1 -0
  42. package/dist/components/preferences/index.js +1 -1
  43. package/dist/components/prompt/atoms/early-tap-script.js +2 -0
  44. package/dist/components/prompt/atoms/overlay.js +1 -1
  45. package/dist/components/prompt/atoms/root.js +1 -1
  46. package/dist/components/prompt/components.js +1 -1
  47. package/dist/components/prompt/policy-actions.js +1 -1
  48. package/dist/components/prompt/prompt.js +1 -1
  49. package/dist/components/shared/dialog-sheets.js +1 -0
  50. package/dist/components/shared/first-paint-sheets.js +1 -0
  51. package/dist/components/shared/iab-dialog-sheets.js +1 -0
  52. package/dist/components/shared/iab-first-paint-sheets.js +1 -0
  53. package/dist/components/shared/libs/compose-refs.js +1 -0
  54. package/dist/components/shared/libs/slot.js +1 -1
  55. package/dist/components/shared/primitives/button.js +1 -1
  56. package/dist/components/shared/primitives/legal-links/index.js +1 -1
  57. package/dist/components/shared/streamed-surface.js +2 -0
  58. package/dist/components/shared/surface-styles.js +2 -0
  59. package/dist/components/shared/ui/dialog/dialog.js +1 -1
  60. package/dist/components/shared/ui/icon.js +1 -1
  61. package/dist/components/shared/ui/logo.js +1 -1
  62. package/dist/components/shared/ui/preference-item/preference-item.js +1 -1
  63. package/dist/consent-gate.js +2 -0
  64. package/dist/consent-theme.js +1 -0
  65. package/dist/context/consent-tracking-context.js +1 -1
  66. package/dist/context/index.js +1 -1
  67. package/dist/context.js +1 -1
  68. package/dist/devtools-launcher.js +2 -0
  69. package/dist/devtools.js +1 -1
  70. package/dist/draft-context.js +2 -0
  71. package/dist/draft.js +1 -1
  72. package/dist/external-iab-context.js +1 -1
  73. package/dist/gpp.js +2 -0
  74. package/dist/headless.js +1 -1
  75. package/dist/hooks/use-color-scheme.js +1 -1
  76. package/dist/hooks/use-committed-ref.js +2 -0
  77. package/dist/hooks/use-focus-trap.js +1 -1
  78. package/dist/hooks/use-headless-iab-consent-ui.js +1 -1
  79. package/dist/hooks/use-iab-policy-guard.js +1 -0
  80. package/dist/hooks/use-late-entry.js +2 -0
  81. package/dist/hooks.js +1 -1
  82. package/dist/iab/styles.tw3.css +5 -45
  83. package/dist/iab-context.js +1 -1
  84. package/dist/iab-dialog-deferred.js +2 -0
  85. package/dist/iab.js +1 -1
  86. package/dist/index-parts/consent-banner.js +1 -0
  87. package/dist/index-parts/consent-dialog-link.js +1 -0
  88. package/dist/index-parts/consent-dialog-trigger.js +1 -0
  89. package/dist/index-parts/consent-dialog.js +1 -0
  90. package/dist/index-parts/consent-gate.js +1 -0
  91. package/dist/index-parts/core.js +1 -0
  92. package/dist/index-parts/draft.js +1 -0
  93. package/dist/index-parts/frame.js +1 -0
  94. package/dist/index-parts/hooks.js +1 -0
  95. package/dist/index-parts/hosted.js +1 -0
  96. package/dist/index-parts/module-hooks.js +1 -0
  97. package/dist/index-parts/offline.js +1 -0
  98. package/dist/index-parts/presets.js +1 -0
  99. package/dist/index-parts/provider.js +1 -0
  100. package/dist/index-parts/theme.js +1 -0
  101. package/dist/index-parts/translations.js +1 -0
  102. package/dist/index.js +1 -1
  103. package/dist/kernel-selector.js +1 -0
  104. package/dist/modes.js +1 -0
  105. package/dist/module-hooks/iframe-blocker.js +1 -1
  106. package/dist/module-hooks/network-blocker.js +1 -1
  107. package/dist/module-hooks/network-hold.js +2 -0
  108. package/dist/module-hooks/persistence.js +1 -1
  109. package/dist/panel-link.js +1 -1
  110. package/dist/panel-trigger.js +1 -1
  111. package/dist/panel.js +1 -1
  112. package/dist/postcss-tailwind3.js +1 -0
  113. package/dist/preferences.js +1 -2
  114. package/dist/provider.js +1 -1
  115. package/dist/server/fetch-ssr-data.js +1 -1
  116. package/dist/server/headers.js +1 -1
  117. package/dist/server/normalize-url.js +1 -1
  118. package/dist/styles.tw3.css +33 -51
  119. package/dist/transports/hosted.js +1 -0
  120. package/dist/transports/manifest.js +1 -0
  121. package/dist/transports/offline.js +1 -1
  122. package/dist/utils/deferred-module.js +2 -0
  123. package/dist/utils/merge-slot-props.js +1 -1
  124. package/dist/utils/theme-utils.js +1 -1
  125. package/dist/version.js +1 -1
  126. package/dist-types/aggregate-components.d.ts +2 -2
  127. package/dist-types/chunk-warming.d.ts +42 -8
  128. package/dist-types/component-hooks/use-headless-consent-ui.d.ts +5 -5
  129. package/dist-types/component-hooks/use-headless-iab-consent-ui.d.ts +2 -2
  130. package/dist-types/components/consent-gate/atoms.d.ts +11 -0
  131. package/dist-types/components/consent-gate/consent-gate.d.ts +2 -0
  132. package/dist-types/components/consent-gate/frame.d.ts +19 -0
  133. package/dist-types/components/consent-gate/index.d.ts +25 -0
  134. package/dist-types/components/{frame → consent-gate}/types.d.ts +7 -7
  135. package/dist-types/components/consent-preferences-link/consent-preferences-link.d.ts +1 -1
  136. package/dist-types/components/consent-preferences-link/index.d.ts +1 -1
  137. package/dist-types/components/iab-panel/atoms/feature-item.d.ts +28 -0
  138. package/dist-types/components/iab-panel/atoms/purpose-item.d.ts +5 -2
  139. package/dist-types/components/iab-panel/atoms/stack-item.d.ts +7 -2
  140. package/dist-types/components/iab-panel/atoms/vendor-list.d.ts +1 -1
  141. package/dist-types/components/iab-panel/iab-panel.d.ts +3 -3
  142. package/dist-types/components/iab-panel/index.d.ts +29 -26
  143. package/dist-types/components/iab-panel/use-iab-translations.d.ts +4 -0
  144. package/dist-types/components/iab-prompt/iab-prompt.d.ts +3 -3
  145. package/dist-types/components/iab-prompt/index.d.ts +19 -19
  146. package/dist-types/components/panel/atoms/card.d.ts +5 -4
  147. package/dist-types/components/panel/atoms/overlay.d.ts +1 -1
  148. package/dist-types/components/panel/index.d.ts +8 -8
  149. package/dist-types/components/panel/panel.d.ts +3 -3
  150. package/dist-types/components/panel-link/index.d.ts +1 -1
  151. package/dist-types/components/panel-trigger/atoms/button.d.ts +1 -1
  152. package/dist-types/components/panel-trigger/atoms/icon.d.ts +1 -1
  153. package/dist-types/components/panel-trigger/atoms/root.d.ts +2 -2
  154. package/dist-types/components/panel-trigger/atoms/toolbar.d.ts +2 -2
  155. package/dist-types/components/panel-trigger/atoms/trigger-icons.d.ts +25 -0
  156. package/dist-types/components/panel-trigger/index.d.ts +4 -4
  157. package/dist-types/components/panel-trigger/panel-trigger-toolbar.d.ts +1 -1
  158. package/dist-types/components/panel-trigger/panel-trigger.d.ts +9 -17
  159. package/dist-types/components/panel-trigger/toolbar-loader.d.ts +34 -0
  160. package/dist-types/components/panel-trigger/types.d.ts +1 -1
  161. package/dist-types/components/preferences/atoms/accordion.d.ts +6 -4
  162. package/dist-types/components/preferences/atoms/button.d.ts +1 -1
  163. package/dist-types/components/preferences/atoms/footer.d.ts +1 -1
  164. package/dist-types/components/preferences/atoms/root.d.ts +1 -1
  165. package/dist-types/components/preferences/atoms/vendor-list.d.ts +23 -0
  166. package/dist-types/components/preferences/index.d.ts +14 -12
  167. package/dist-types/components/preferences/policy-actions.d.ts +2 -2
  168. package/dist-types/components/preferences/preferences.d.ts +1 -1
  169. package/dist-types/components/preferences/types.d.ts +1 -1
  170. package/dist-types/components/prompt/atoms/early-tap-script.d.ts +17 -0
  171. package/dist-types/components/prompt/atoms/root.d.ts +4 -0
  172. package/dist-types/components/prompt/components.d.ts +9 -3
  173. package/dist-types/components/prompt/index.d.ts +12 -12
  174. package/dist-types/components/prompt/policy-actions.d.ts +2 -2
  175. package/dist-types/components/prompt/prompt.d.ts +5 -1
  176. package/dist-types/components/shared/dialog-sheets.d.ts +9 -0
  177. package/dist-types/components/shared/first-paint-sheets.d.ts +8 -0
  178. package/dist-types/components/shared/iab-dialog-sheets.d.ts +3 -0
  179. package/dist-types/components/shared/iab-first-paint-sheets.d.ts +3 -0
  180. package/dist-types/components/shared/libs/compose-refs.d.ts +20 -0
  181. package/dist-types/components/shared/policy-actions.d.ts +2 -2
  182. package/dist-types/components/shared/primitives/box.d.ts +1 -1
  183. package/dist-types/components/shared/primitives/button.d.ts +2 -2
  184. package/dist-types/components/shared/primitives/button.types.d.ts +1 -1
  185. package/dist-types/components/shared/streamed-surface.d.ts +23 -0
  186. package/dist-types/components/shared/surface-styles.d.ts +60 -0
  187. package/dist-types/components/shared/ui/accordion/accordion.d.ts +2 -2
  188. package/dist-types/components/shared/ui/accordion/index.d.ts +2 -2
  189. package/dist-types/components/shared/ui/animated-collapse/index.d.ts +2 -2
  190. package/dist-types/components/shared/ui/branding.d.ts +1 -1
  191. package/dist-types/components/shared/ui/button/button.d.ts +1 -1
  192. package/dist-types/components/shared/ui/button/index.d.ts +2 -2
  193. package/dist-types/components/shared/ui/collapsible/index.d.ts +1 -1
  194. package/dist-types/components/shared/ui/dialog/index.d.ts +1 -1
  195. package/dist-types/components/shared/ui/icon.d.ts +2 -1
  196. package/dist-types/components/shared/ui/logo.d.ts +0 -10
  197. package/dist-types/components/shared/ui/preference-item/index.d.ts +1 -1
  198. package/dist-types/components/shared/ui/preference-item/preference-item.d.ts +13 -0
  199. package/dist-types/components/shared/ui/switch/index.d.ts +2 -2
  200. package/dist-types/components/shared/ui/switch/switch.d.ts +1 -1
  201. package/dist-types/components/shared/ui/tabs/index.d.ts +1 -1
  202. package/dist-types/consent-gate.d.ts +1 -0
  203. package/dist-types/consent-theme.d.ts +38 -0
  204. package/dist-types/context/consent-tracking-context.d.ts +10 -0
  205. package/dist-types/context/index.d.ts +3 -3
  206. package/dist-types/context/theme-context.d.ts +3 -3
  207. package/dist-types/context.d.ts +25 -1
  208. package/dist-types/devtools-launcher.d.ts +29 -0
  209. package/dist-types/devtools.d.ts +13 -2
  210. package/dist-types/draft-context.d.ts +31 -0
  211. package/dist-types/draft.d.ts +81 -9
  212. package/dist-types/gpp.d.ts +27 -0
  213. package/dist-types/headless.d.ts +6 -7
  214. package/dist-types/hooks/use-committed-ref.d.ts +24 -0
  215. package/dist-types/hooks/use-focus-trap.d.ts +3 -1
  216. package/dist-types/hooks/use-headless-iab-consent-ui.d.ts +1 -1
  217. package/dist-types/hooks/use-iab-manager.d.ts +5 -5
  218. package/dist-types/hooks/use-iab-policy-guard.d.ts +35 -0
  219. package/dist-types/hooks/use-late-entry.d.ts +14 -0
  220. package/dist-types/hooks/use-theme.d.ts +1 -1
  221. package/dist-types/hooks.d.ts +106 -11
  222. package/dist-types/iab-dialog-deferred.d.ts +36 -0
  223. package/dist-types/iab.d.ts +8 -7
  224. package/dist-types/index-parts/consent-banner.d.ts +7 -0
  225. package/dist-types/index-parts/consent-dialog-link.d.ts +7 -0
  226. package/dist-types/index-parts/consent-dialog-trigger.d.ts +7 -0
  227. package/dist-types/index-parts/consent-dialog.d.ts +7 -0
  228. package/dist-types/index-parts/consent-gate.d.ts +7 -0
  229. package/dist-types/index-parts/core.d.ts +7 -0
  230. package/dist-types/index-parts/draft.d.ts +7 -0
  231. package/dist-types/index-parts/frame.d.ts +7 -0
  232. package/dist-types/index-parts/hooks.d.ts +7 -0
  233. package/dist-types/index-parts/hosted.d.ts +7 -0
  234. package/dist-types/index-parts/module-hooks.d.ts +7 -0
  235. package/dist-types/index-parts/offline.d.ts +7 -0
  236. package/dist-types/index-parts/presets.d.ts +7 -0
  237. package/dist-types/index-parts/provider.d.ts +7 -0
  238. package/dist-types/index-parts/theme.d.ts +8 -0
  239. package/dist-types/index-parts/translations.d.ts +7 -0
  240. package/dist-types/index.d.ts +32 -28
  241. package/dist-types/kernel-selector.d.ts +68 -0
  242. package/dist-types/modes.d.ts +26 -0
  243. package/dist-types/module-hooks/iframe-blocker.d.ts +33 -1
  244. package/dist-types/module-hooks/network-blocker.d.ts +23 -0
  245. package/dist-types/module-hooks/network-hold.d.ts +47 -0
  246. package/dist-types/module-hooks.d.ts +4 -4
  247. package/dist-types/panel-link.d.ts +1 -1
  248. package/dist-types/panel-trigger.d.ts +1 -1
  249. package/dist-types/panel.d.ts +13 -1
  250. package/dist-types/postcss-tailwind3.d.ts +21 -0
  251. package/dist-types/preferences.d.ts +12 -1
  252. package/dist-types/primitives/accordion.d.ts +1 -1
  253. package/dist-types/primitives/button.d.ts +1 -1
  254. package/dist-types/primitives/collapsible.d.ts +1 -1
  255. package/dist-types/primitives/dialog.d.ts +1 -1
  256. package/dist-types/primitives/preference-item.d.ts +1 -1
  257. package/dist-types/primitives/switch.d.ts +1 -1
  258. package/dist-types/primitives/tabs.d.ts +1 -1
  259. package/dist-types/primitives.d.ts +7 -7
  260. package/dist-types/prompt.d.ts +1 -1
  261. package/dist-types/provider.d.ts +169 -28
  262. package/dist-types/server/fetch-ssr-data.d.ts +1 -1
  263. package/dist-types/server/headers.d.ts +14 -4
  264. package/dist-types/server/index.d.ts +5 -5
  265. package/dist-types/server/normalize-url.d.ts +14 -7
  266. package/dist-types/server/types.d.ts +12 -1
  267. package/dist-types/theme-provider.d.ts +2 -2
  268. package/dist-types/transports/hosted.d.ts +36 -0
  269. package/dist-types/transports/manifest.d.ts +48 -0
  270. package/dist-types/transports/offline.d.ts +7 -16
  271. package/dist-types/types/index.d.ts +3 -3
  272. package/dist-types/types/manager.d.ts +1 -1
  273. package/dist-types/types/theme/index.d.ts +1 -1
  274. package/dist-types/ui-config-context.d.ts +14 -2
  275. package/dist-types/utils/deferred-module.d.ts +13 -0
  276. package/dist-types/utils/index.d.ts +4 -4
  277. package/dist-types/utils/merge-slot-props.d.ts +17 -3
  278. package/dist-types/utils/merge-styles.d.ts +1 -1
  279. package/dist-types/utils/theme-utils.d.ts +18 -3
  280. package/dist-types/version.d.ts +1 -1
  281. package/docs/README.md +97 -70
  282. package/docs/assets/v3/bottom-bar.png +0 -0
  283. package/docs/assets/v3/brand-card.png +0 -0
  284. package/docs/assets/v3/brand-preferences.png +0 -0
  285. package/docs/assets/v3/choice-wall.png +0 -0
  286. package/docs/assets/v3/headless-bar-html.png +0 -0
  287. package/docs/assets/v3/headless-bar-mobile.png +0 -0
  288. package/docs/assets/v3/headless-bar.png +0 -0
  289. package/docs/assets/v3/slim-bar.png +0 -0
  290. package/docs/concepts/choose-your-setup.md +141 -0
  291. package/docs/concepts/consent-categories.md +84 -0
  292. package/docs/concepts/consent-state.md +421 -0
  293. package/docs/concepts/data-fetching.md +284 -0
  294. package/docs/concepts/how-consent-works.md +123 -0
  295. package/docs/concepts/modes.md +281 -0
  296. package/docs/{frameworks/react/concepts/policy-presets.md → concepts/policies.md} +8 -60
  297. package/docs/customization/class-names.md +202 -0
  298. package/docs/customization/dark-mode.md +157 -0
  299. package/docs/customization/motion.md +128 -0
  300. package/docs/customization/overview.md +68 -33
  301. package/docs/customization/recipes.md +838 -47
  302. package/docs/customization/slots.md +217 -35
  303. package/docs/customization/stylesheets.md +248 -0
  304. package/docs/customization/tailwind.md +863 -0
  305. package/docs/customization/tokens.md +167 -36
  306. package/docs/customization/translations.md +87 -3
  307. package/docs/frameworks/react/callbacks.md +118 -0
  308. package/docs/frameworks/react/clear-on-revocation.md +106 -0
  309. package/docs/frameworks/react/components/consent-banner.md +48 -27
  310. package/docs/frameworks/react/components/consent-dialog-link.md +13 -11
  311. package/docs/frameworks/react/components/consent-dialog-trigger.md +86 -76
  312. package/docs/frameworks/react/components/consent-dialog.md +111 -58
  313. package/docs/frameworks/react/components/{frame.md → consent-gate.md} +70 -49
  314. package/docs/frameworks/react/components/consent-provider.md +143 -0
  315. package/docs/frameworks/react/components/consent-widget.md +69 -24
  316. package/docs/frameworks/react/components/dev-tools.md +76 -85
  317. package/docs/frameworks/react/components.md +113 -0
  318. package/docs/frameworks/react/compose.md +354 -0
  319. package/docs/frameworks/react/content-security-policy.md +149 -0
  320. package/docs/frameworks/react/customize.md +258 -0
  321. package/docs/frameworks/react/embeds.md +89 -0
  322. package/docs/frameworks/react/gpp.md +163 -0
  323. package/docs/frameworks/react/headless.md +4 -4
  324. package/docs/frameworks/react/hooks.md +70 -0
  325. package/docs/frameworks/react/iab.md +278 -0
  326. package/docs/frameworks/react/network-blocker.md +140 -0
  327. package/docs/frameworks/react/quickstart.md +171 -107
  328. package/docs/frameworks/react/rendering.md +285 -0
  329. package/docs/frameworks/react/scripts.md +114 -0
  330. package/docs/frameworks/react/translations.md +155 -0
  331. package/docs/frameworks/react/troubleshooting.md +189 -61
  332. package/docs/frameworks/react/upgrade-v3.md +652 -0
  333. package/docs/frameworks/react/vendor-consent.md +188 -0
  334. package/docs/guides/banner-experiments.md +688 -0
  335. package/docs/guides/troubleshooting.md +192 -54
  336. package/docs/guides/verify-consent.md +96 -49
  337. package/docs/integrations/adobe-analytics.md +177 -183
  338. package/docs/integrations/ahrefs-analytics.md +162 -178
  339. package/docs/integrations/amplitude.md +172 -180
  340. package/docs/integrations/building-integrations.md +137 -33
  341. package/docs/integrations/clearbit.md +164 -178
  342. package/docs/integrations/cloudflare-web-analytics.md +166 -180
  343. package/docs/integrations/cloudflare-zaraz.md +333 -0
  344. package/docs/integrations/crisp.md +174 -182
  345. package/docs/integrations/databuddy.md +167 -197
  346. package/docs/integrations/fathom-analytics.md +168 -180
  347. package/docs/integrations/front-chat.md +308 -0
  348. package/docs/integrations/google-maps.md +142 -108
  349. package/docs/integrations/google-tag-manager.md +258 -185
  350. package/docs/integrations/google-tag.md +226 -182
  351. package/docs/integrations/heap.md +173 -179
  352. package/docs/integrations/hightouch.md +171 -181
  353. package/docs/integrations/hotjar.md +169 -179
  354. package/docs/integrations/intercom.md +193 -177
  355. package/docs/integrations/klaviyo.md +473 -0
  356. package/docs/integrations/linkedin-insights.md +184 -174
  357. package/docs/integrations/logrocket.md +170 -180
  358. package/docs/integrations/matomo-analytics.md +198 -202
  359. package/docs/integrations/meta-pixel.md +198 -174
  360. package/docs/integrations/microsoft-clarity.md +173 -179
  361. package/docs/integrations/microsoft-uet.md +158 -178
  362. package/docs/integrations/mixpanel-analytics.md +165 -184
  363. package/docs/integrations/one-dollar-stats.md +292 -0
  364. package/docs/integrations/openai-pixel.md +214 -325
  365. package/docs/integrations/overview.md +153 -83
  366. package/docs/integrations/pinterest-tag.md +315 -0
  367. package/docs/integrations/pirsch.md +179 -183
  368. package/docs/integrations/plausible-analytics.md +182 -182
  369. package/docs/integrations/posthog.md +323 -264
  370. package/docs/integrations/promptwatch.md +164 -178
  371. package/docs/integrations/reddit-pixel.md +195 -181
  372. package/docs/integrations/rudderstack.md +211 -210
  373. package/docs/integrations/rybbit-analytics.md +181 -184
  374. package/docs/integrations/segment.md +192 -178
  375. package/docs/integrations/sentry.md +402 -0
  376. package/docs/integrations/snapchat-pixel.md +196 -180
  377. package/docs/integrations/tiktok-pixel.md +181 -174
  378. package/docs/integrations/umami-analytics.md +173 -182
  379. package/docs/integrations/vercel-analytics.md +176 -181
  380. package/docs/integrations/vercel-speed-insights.md +306 -0
  381. package/docs/integrations/x-pixel.md +186 -174
  382. package/docs/integrations/youtube.md +150 -111
  383. package/package.json +48 -17
  384. package/dist/component-hooks/use-manager.js +0 -2
  385. package/dist/components/frame/atoms.js +0 -1
  386. package/dist/components/frame/frame.js +0 -2
  387. package/dist/components/frame/index.js +0 -2
  388. package/dist/frame.js +0 -2
  389. package/dist/ui-save.js +0 -1
  390. package/dist-types/component-hooks/use-manager.d.ts +0 -40
  391. package/dist-types/components/frame/atoms.d.ts +0 -11
  392. package/dist-types/components/frame/frame.d.ts +0 -2
  393. package/dist-types/components/frame/index.d.ts +0 -24
  394. package/dist-types/frame.d.ts +0 -1
  395. package/dist-types/ui-save.d.ts +0 -5
  396. package/docs/assets/v3/brand-bar.png +0 -0
  397. package/docs/assets/v3/mobile-card.png +0 -0
  398. package/docs/assets/v3/preferences.png +0 -0
  399. package/docs/frameworks/react/components/consent-manager-provider.md +0 -71
  400. package/docs/frameworks/react/concepts/consent-categories.md +0 -33
  401. package/docs/frameworks/react/hooks/use-consent-manager/overview.md +0 -58
  402. package/docs/frameworks/react/iab/overview.md +0 -53
  403. package/docs/frameworks/react/script-loader.md +0 -63
  404. package/docs/frameworks/react/styling/overview.md +0 -217
  405. package/docs/guides/consent-state.md +0 -60
  406. package/docs/guides/data-fetching.md +0 -163
  407. package/docs/guides/deployment-modes.md +0 -63
  408. package/docs/integrations/clear-on-revocation.md +0 -167
  409. package/docs/upgrade-v3.md +0 -334
  410. package/readme.json +0 -48
  411. package/src/iab/styles.css +0 -11
  412. package/src/styles.css +0 -10
  413. /package/dist/components/{frame → consent-gate}/types.js +0 -0
@@ -1,6 +1,38 @@
1
- import type { IframeBlockerHandle } from '@c15t/core/modules/iframe-blocker';
1
+ import type { ConsentKernel } from '@c15t/core';
2
+ import type { IframeBlockerHandle, IframeBlockerOptions } from '@c15t/core/modules/iframe-blocker';
2
3
  export interface UseIframeBlockerOptions {
3
4
  disableAutomaticBlocking?: boolean;
4
5
  }
5
6
  export declare const useIframeBlocker: (options?: UseIframeBlockerOptions) => IframeBlockerHandle;
7
+ /**
8
+ * Call `onFound` when a gated iframe is on the page: at once when one is
9
+ * there already, and again for each batch of gated frames that arrives.
10
+ *
11
+ * Until the returned stop function runs, a gated frame that arrives with a
12
+ * `src` the snapshot does not clearly allow is paused (`src` moved to
13
+ * `data-src`), as the loaded blocker would pause it. Frames on the page at
14
+ * the first call are left to the blocker, which is what happens when it
15
+ * loads with the provider.
16
+ *
17
+ * @param kernel - The kernel whose snapshot decides what is clearly allowed.
18
+ * @param onFound - Called for every sighting; the caller dedupes.
19
+ * @returns Stops watching.
20
+ * @internal
21
+ */
22
+ export declare const watchGatedIframes: (kernel: ConsentKernel, onFound: () => void) => () => void;
23
+ /**
24
+ * The provider's iframe blocker. Loads the blocker module when the first
25
+ * gated iframe (`data-category` or `data-vendor`) is on the page instead of
26
+ * on every mount, so pages without one never download it. Until then it
27
+ * pauses gated frames that arrive with a `src` consent does not allow.
28
+ *
29
+ * Passed to the provider runtime as its `createIframeBlocker` module.
30
+ *
31
+ * @param options - The kernel and blocker options. With
32
+ * `disableAutomaticBlocking` the module loads at once.
33
+ * @returns A handle; `processAllIframes()` reaches the blocker once it has
34
+ * loaded.
35
+ * @internal
36
+ */
37
+ export declare const createIframeBlockerOnDemand: ({ disableAutomaticBlocking, kernel, }: IframeBlockerOptions) => IframeBlockerHandle;
6
38
  export type { IframeBlockerHandle };
@@ -5,5 +5,28 @@ export interface UseNetworkBlockerOptions {
5
5
  logBlockedRequests?: boolean;
6
6
  onRequestBlocked?: (info: BlockedRequestInfo) => void;
7
7
  }
8
+ /**
9
+ * Block `fetch` and XHR requests that match `rules` until the visitor's
10
+ * consent allows them.
11
+ *
12
+ * Blocking starts during the first render in the browser: matching requests
13
+ * wait from then on, including ones sent from this component's children's
14
+ * mount effects and from effects that run before this component's. The
15
+ * blocker loads after mount and decides each waiting request. On the
16
+ * server the hook does nothing.
17
+ *
18
+ * Rendering has a side effect: the first render patches `fetch` and
19
+ * `XMLHttpRequest` to hold matching requests. If React discards that
20
+ * render and never commits it, the hold ends after 10 seconds. Nothing
21
+ * checked consent for the requests it held, so they fail as blocked: a 451
22
+ * response for `fetch`, a failed XHR.
23
+ *
24
+ * Prefer the provider's `networkBlocker` option. It starts blocking when
25
+ * the provider renders, so it also covers components rendered before this
26
+ * one.
27
+ *
28
+ * @param options - Rules and logging options.
29
+ * @returns A handle to update rules or toggle blocking.
30
+ */
8
31
  export declare const useNetworkBlocker: (options: UseNetworkBlockerOptions) => NetworkBlockerHandle;
9
32
  export type { BlockedRequestInfo, NetworkBlockerHandle, NetworkBlockerRule };
@@ -0,0 +1,47 @@
1
+ import type { NetworkBlockerRule } from '@c15t/core/modules/network-blocker';
2
+ import type { NetworkHold } from '@c15t/core/modules/network-hold';
3
+ /**
4
+ * How long a hold started during render waits for its component to commit.
5
+ * A render React throws away never commits, so nothing else would end its
6
+ * hold. When this runs out the hold ends, and since nothing checked consent
7
+ * for the requests it held, they get the blocker's answer for a blocked
8
+ * request instead of being sent.
9
+ * @internal
10
+ */
11
+ export declare const UNCOMMITTED_HOLD_MS = 10000;
12
+ /**
13
+ * The render-time hold behind one network blocker mount.
14
+ * @internal
15
+ */
16
+ export interface EarlyNetworkHold {
17
+ /**
18
+ * Call from the mount effect, before loading the blocker. Keeps the hold
19
+ * from expiring, starts a new one if it already ended (a StrictMode or
20
+ * kernel re-run after the blocker took over, or a commit that came after
21
+ * the expiry), and returns it for `createNetworkBlocker({ hold })`. A
22
+ * disabled blocker gets a hold that holds nothing, so it cannot end
23
+ * another caller's hold.
24
+ */
25
+ claim: (rules: readonly NetworkBlockerRule[], enabled: boolean | undefined) => NetworkHold;
26
+ /**
27
+ * Call from the mount effect's cleanup. Ends a hold no blocker took
28
+ * over, unless the effect runs again first (StrictMode, a kernel change).
29
+ * Nothing checked consent for what that hold held, so those requests get
30
+ * the blocker's answer for a blocked request instead of being sent.
31
+ */
32
+ unmount: () => void;
33
+ }
34
+ /**
35
+ * Hold requests matching `rules` from this component's first render in the
36
+ * browser, before any child renders or runs an effect. The network blocker
37
+ * loads after mount and takes the hold over.
38
+ *
39
+ * Rendering is not side-effect free: the first render patches `fetch` and
40
+ * `XMLHttpRequest`. That is safe because the hold only delays matching
41
+ * requests, a render React discards ends its hold after
42
+ * {@link UNCOMMITTED_HOLD_MS} (failing what it held as blocked), and on the
43
+ * server it does nothing.
44
+ *
45
+ * @internal
46
+ */
47
+ export declare const useEarlyNetworkHold: (rules: readonly NetworkBlockerRule[], enabled: boolean | undefined) => EarlyNetworkHold;
@@ -1,4 +1,4 @@
1
- export { type IframeBlockerHandle, type UseIframeBlockerOptions, useIframeBlocker, } from './module-hooks/iframe-blocker';
2
- export { type BlockedRequestInfo, type NetworkBlockerHandle, type NetworkBlockerRule, type UseNetworkBlockerOptions, useNetworkBlocker, } from './module-hooks/network-blocker';
3
- export { type PersistenceHandle, type PersistenceOptions, type UsePersistenceOptions, usePersistence, } from './module-hooks/persistence';
4
- export { type Script, type ScriptLoaderDebugEvent, type ScriptLoaderHandle, type UseScriptLoaderOptions, useScriptLoader, } from './module-hooks/script-loader';
1
+ export { type IframeBlockerHandle, type UseIframeBlockerOptions, useIframeBlocker, } from './module-hooks/iframe-blocker.js';
2
+ export { type BlockedRequestInfo, type NetworkBlockerHandle, type NetworkBlockerRule, type UseNetworkBlockerOptions, useNetworkBlocker, } from './module-hooks/network-blocker.js';
3
+ export { type PersistenceHandle, type PersistenceOptions, type UsePersistenceOptions, usePersistence, } from './module-hooks/persistence.js';
4
+ export { type Script, type ScriptLoaderDebugEvent, type ScriptLoaderHandle, type UseScriptLoaderOptions, useScriptLoader, } from './module-hooks/script-loader.js';
@@ -1 +1 @@
1
- export * from './components/panel-link';
1
+ export { ConsentDialogLink, type ConsentDialogLinkProps, } from './components/panel-link/index.js';
@@ -1 +1 @@
1
- export * from './components/panel-trigger';
1
+ export { ConsentDialogTrigger, type ConsentDialogTriggerCompound, type ConsentDialogTriggerProps, ConsentDialogTriggerToolbar, type ConsentDialogTriggerToolbarAction, type ConsentDialogTriggerToolbarPreferences, type ConsentDialogTriggerToolbarProps, type CornerPosition, TriggerButton, type TriggerButtonProps, TriggerIcon, type TriggerIconProps, type TriggerIconType, type TriggerOrientation, TriggerRoot, type TriggerRootProps, type TriggerSize, TriggerText, type TriggerTextProps, type TriggerVisibility, type UseDraggableOptions, type UseDraggableReturn, useDraggable, useTriggerContext, } from './components/panel-trigger/index.js';
@@ -1 +1,13 @@
1
- export * from './components/panel';
1
+ /**
2
+ * `@c15t/react/consent-dialog`: the deferred `ConsentDialog`, the same
3
+ * component the `@c15t/react` entry exports. Its implementation and styles
4
+ * load when the dialog first opens, or earlier when something preloads it,
5
+ * so importing this entry adds nothing heavy to the first load.
6
+ *
7
+ * The eager dialog and its individual parts (`Card`, `Header`, `Overlay`,
8
+ * ...) are in `@c15t/react/components/consent-dialog`.
9
+ *
10
+ * @packageDocumentation
11
+ */
12
+ export { ConsentDialog } from './aggregate-components.js';
13
+ export type { ConsentDialogCompoundComponent, ConsentDialogProps, } from './components/panel/index.js';
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Tailwind 3 PostCSS plugin for c15t stylesheets, re-exported from
3
+ * `@c15t/ui/postcss-tailwind3` so an app that installs `@c15t/react` can list
4
+ * `@c15t/react/postcss-tailwind3` without installing `@c15t/ui`.
5
+ * See `@c15t/ui/postcss-tailwind3` for what the plugin does. It must come
6
+ * before `tailwindcss`.
7
+ *
8
+ * @example
9
+ * ```js
10
+ * // postcss.config.mjs
11
+ * export default {
12
+ * plugins: {
13
+ * '@c15t/react/postcss-tailwind3': {},
14
+ * tailwindcss: {},
15
+ * autoprefixer: {},
16
+ * },
17
+ * };
18
+ * ```
19
+ */
20
+ export * from '@c15t/ui/postcss-tailwind3';
21
+ export { default } from '@c15t/ui/postcss-tailwind3';
@@ -1 +1,12 @@
1
- export * from './components/preferences';
1
+ /**
2
+ * `@c15t/react/consent-widget`: the deferred `ConsentWidget`, the same
3
+ * component the `@c15t/react` entry exports. Its implementation and styles
4
+ * load when the widget first renders.
5
+ *
6
+ * The eager widget and its individual parts (`Accordion`, `Switch`, `Footer`,
7
+ * ...) are in `@c15t/react/components/consent-widget`.
8
+ *
9
+ * @packageDocumentation
10
+ */
11
+ export { ConsentWidget } from './aggregate-components.js';
12
+ export type { ConsentWidgetCompoundComponent, ConsentWidgetProps, } from './components/preferences/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/accordion';
1
+ export * from '../components/shared/ui/accordion/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/button';
1
+ export * from '../components/shared/ui/button/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/collapsible';
1
+ export * from '../components/shared/ui/collapsible/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/dialog';
1
+ export * from '../components/shared/ui/dialog/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/preference-item';
1
+ export * from '../components/shared/ui/preference-item/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/switch';
1
+ export * from '../components/shared/ui/switch/index.js';
@@ -1 +1 @@
1
- export * from '../components/shared/ui/tabs';
1
+ export * from '../components/shared/ui/tabs/index.js';
@@ -1,7 +1,7 @@
1
- export * as Accordion from './components/shared/ui/accordion';
2
- export * as Button from './components/shared/ui/button';
3
- export * as Collapsible from './components/shared/ui/collapsible';
4
- export * as Dialog from './components/shared/ui/dialog';
5
- export * as PreferenceItem from './components/shared/ui/preference-item';
6
- export * as Switch from './components/shared/ui/switch';
7
- export * as Tabs from './components/shared/ui/tabs';
1
+ export * as Accordion from './components/shared/ui/accordion/index.js';
2
+ export * as Button from './components/shared/ui/button/index.js';
3
+ export * as Collapsible from './components/shared/ui/collapsible/index.js';
4
+ export * as Dialog from './components/shared/ui/dialog/index.js';
5
+ export * as PreferenceItem from './components/shared/ui/preference-item/index.js';
6
+ export * as Switch from './components/shared/ui/switch/index.js';
7
+ export * as Tabs from './components/shared/ui/tabs/index.js';
@@ -1 +1 @@
1
- export * from './components/prompt';
1
+ export * from './components/prompt/index.js';
@@ -1,27 +1,68 @@
1
- import type { AllConsentNames, ClearOnRevocationConfig, ConsentPresentation, Callbacks, I18nConfig, KernelConfig, KernelOverrides, KernelUser, LegalLinks, ProviderTransportFactory, StorageConfig, User } from '@c15t/core';
1
+ import type { AllConsentNames, Callbacks, ClearOnRevocationConfig, ConsentExperiment, ConsentJourneyOption, ConsentPresentation, ExperimentState, JourneyState, I18nConfig, KernelConfig, KernelOverrides, KernelUser, LegalLinks, ProviderTransportFactory, StorageConfig, User, Vendor } from '@c15t/core';
2
2
  import type { Script } from '@c15t/core/modules/script-loader';
3
- import type { ConsentRuntime } from '@c15t/core/runtime';
3
+ import type { ConsentControlOptions } from '@c15t/core/runtime';
4
+ import type { ConsentRuntime, ConsentRuntimeModules, ResolveStreamedInit } from '@c15t/core/runtime/provider';
4
5
  import type { ReactNode } from 'react';
5
- import type { UseNetworkBlockerOptions, UsePersistenceOptions, UseScriptLoaderOptions } from './module-hooks';
6
- import type { ReactUIOptions } from './types/manager';
7
- import type { ReactComponentSlots } from './types/slots';
6
+ import type { DialogPreload } from './chunk-warming.js';
7
+ import type { UseNetworkBlockerOptions, UsePersistenceOptions, UseScriptLoaderOptions } from './module-hooks.js';
8
+ import type { UseIframeBlockerOptions } from './module-hooks/iframe-blocker.js';
9
+ import type { ReactUIOptions } from './types/manager.js';
10
+ import type { ReactComponentSlots } from './types/slots.js';
8
11
  /** Events emitted by the mounted provider without snapshot-derived consent aliases. */
9
- export type ConsentProviderCallbacks = Pick<Callbacks, 'onChoiceRecorded' | 'onPermissionsChanged' | 'onError'>;
10
- /** Prepared policy and records; legacy consent projections are not provider inputs. */
11
- export type ConsentProviderPrefetch = Omit<KernelConfig, 'initialDraft' | 'transport'>;
12
- export interface ConsentProviderOptions extends Pick<ReactUIOptions, 'colorScheme' | 'disableAnimation' | 'noStyle' | 'scrollLock' | 'theme' | 'trapFocus'> {
12
+ export type ConsentProviderCallbacks = Pick<Callbacks, 'onChoiceRecorded' | 'onPermissionsChanged' | 'onSurfaceShown' | 'onError' | 'onBeforeConsentRevocationReload'>;
13
+ /**
14
+ * Prepared policy and records; legacy consent projections are not provider
15
+ * inputs. An `experiment` a server helper resolved runs instead of
16
+ * `options.experiment`, and a `journey` it started is the one the provider
17
+ * continues.
18
+ */
19
+ export type ConsentProviderPrefetch = Omit<KernelConfig, 'initialDraft' | 'transport'> & ExperimentState & JourneyState;
20
+ export interface ConsentProviderOptions extends ConsentControlOptions, Pick<ReactUIOptions, 'colorScheme' | 'disableAnimation' | 'noStyle' | 'scrollLock' | 'theme' | 'trapFocus'> {
13
21
  enabled?: boolean;
14
22
  presentation?: ConsentPresentation;
23
+ /**
24
+ * A/B experiment on prompt/preferences presentation. The assigned arm is
25
+ * merged over `presentation`, exposed through `useExperiment()`, and
26
+ * recorded with every impression and choice. Initial-only: remount the
27
+ * provider to change the experiment.
28
+ */
29
+ experiment?: ConsentExperiment;
30
+ /**
31
+ * Random journey id that links each `/init` to the save that follows:
32
+ * `'page'`, `'tab'` or `false`. Initial-only.
33
+ *
34
+ * @default 'page'
35
+ */
36
+ journey?: ConsentJourneyOption;
15
37
  /**
16
38
  * Content Security Policy nonce applied to DOM nodes c15t injects.
17
39
  *
18
40
  * @remarks
19
41
  * Set this when your CSP uses a nonce-based policy instead of
20
- * `'unsafe-inline'`. The provider forwards it to the injected theme
21
- * `<style>` element and to every `<script>` element created by the
22
- * script loader. A per-script `nonce` still takes precedence.
42
+ * `'unsafe-inline'`. The provider forwards it to every `<script>`
43
+ * element created by the script loader, and to the `<style>` elements
44
+ * the stock surfaces render. A per-script `nonce` still takes
45
+ * precedence. Pass the same nonce to `ConsentTheme`, which renders the
46
+ * theme `<style>` element.
23
47
  */
24
48
  nonce?: string;
49
+ /**
50
+ * Whether the stock surfaces render their own stylesheets.
51
+ *
52
+ * @remarks
53
+ * The banner, dialog trigger, ConsentGate, dialog and preference widget
54
+ * each render the c15t rules they use as a `<style>` element: in the
55
+ * server-rendered HTML, or with the surface's own code in the browser.
56
+ * No c15t stylesheet `<link>` then holds back the page's first paint.
57
+ * React 19 moves them into `<head>` and renders each once. They carry
58
+ * {@link ConsentProviderOptions.nonce}.
59
+ *
60
+ * Set `false` when the app imports `styles.css` itself, for example to
61
+ * run it through Tailwind CSS 3 or to put it in a named cascade layer.
62
+ *
63
+ * @default true
64
+ */
65
+ styles?: boolean;
25
66
  /**
26
67
  * Transport factory the provider builds its kernel with. Required.
27
68
  *
@@ -34,7 +75,7 @@ export interface ConsentProviderOptions extends Pick<ReactUIOptions, 'colorSchem
34
75
  * ```tsx
35
76
  * import { ConsentProvider, hosted, offline } from '@c15t/react';
36
77
  *
37
- * <ConsentProvider options={{ mode: hosted({ url: '/api/c15t' }) }}>
78
+ * <ConsentProvider options={{ mode: hosted({ backendURL: '/api/c15t' }) }}>
38
79
  * {children}
39
80
  * </ConsentProvider>
40
81
  *
@@ -42,6 +83,12 @@ export interface ConsentProviderOptions extends Pick<ReactUIOptions, 'colorSchem
42
83
  * ```
43
84
  */
44
85
  mode: ProviderTransportFactory;
86
+ /**
87
+ * Where the visitor's choice is stored. Read once, like `persistence`:
88
+ * the stored records and the data clearing that protects them stay at
89
+ * the location the provider mounted with. Outside production, a change
90
+ * logs a warning; remount the provider to move storage.
91
+ */
45
92
  storageConfig?: StorageConfig;
46
93
  user?: User | KernelUser;
47
94
  overrides?: KernelOverrides;
@@ -56,9 +103,12 @@ export interface ConsentProviderOptions extends Pick<ReactUIOptions, 'colorSchem
56
103
  * Pass the pending `Promise<KernelConfig>` instead and the provider
57
104
  * mounts at once with a provisional policy, so `children` render (and
58
105
  * the static shell can prerender) while the consent data streams in.
59
- * Consent surfaces stay hidden until the promise resolves; its first
60
- * `init()` then applies the resolved config in place of the transport's
61
- * network init. A config that resolves without a policy (persisted
106
+ * Consent surfaces stay hidden until the promise resolves. On the
107
+ * server, `ConsentBanner` waits for it in its own Suspense boundary and
108
+ * follows the page in a later chunk of the same response, before
109
+ * hydration, when the resolved policy shows a banner; see
110
+ * `streamBanner`. The resolved config then answers the first `init()`
111
+ * in place of the transport's network init. A config that resolves without a policy (persisted
62
112
  * consents, geo, language only) is applied to the kernel and the
63
113
  * transport init runs as usual; a rejected promise is logged outside
64
114
  * production and falls through to the transport init. Initial-only:
@@ -69,33 +119,109 @@ export interface ConsentProviderOptions extends Pick<ReactUIOptions, 'colorSchem
69
119
  * // app/layout.tsx — stays synchronous, so the shell prerenders.
70
120
  * const config = resolveConsent({ backendURL });
71
121
  * return (
72
- * <ConsentProvider options={{ mode: hosted({ url }), prefetch: config }}>
122
+ * <ConsentProvider options={{ mode: hosted({ backendURL }), prefetch: config }}>
73
123
  * {children}
74
124
  * </ConsentProvider>
75
125
  * );
76
126
  * ```
77
127
  */
78
128
  prefetch?: ConsentProviderPrefetch | Promise<ConsentProviderPrefetch>;
129
+ /**
130
+ * Whether `ConsentBanner` renders on the server once a `prefetch`
131
+ * promise resolves, so it arrives in the streamed response before the
132
+ * page hydrates. It shows only when the resolved policy shows a banner
133
+ * for this visitor. Set `false` to mount the banner after hydration
134
+ * instead, as with a client-only provider. No effect when `prefetch` is
135
+ * not a promise. Use the same value on the server and in the browser.
136
+ *
137
+ * @default true
138
+ */
139
+ streamBanner?: boolean;
79
140
  callbacks?: ConsentProviderCallbacks;
80
141
  /**
81
142
  * Remove configured browser data when its consent permission is revoked.
82
143
  * Initial-only: remount the provider to replace its cleanup configuration.
83
144
  */
84
145
  clearOnRevocation?: ClearOnRevocationConfig;
146
+ /**
147
+ * Reload the page after an accept, reject or save turns off a category or
148
+ * vendor that was granted, or after a `consentSource` withdraws one.
149
+ * Removing a script cannot stop code that already ran, so the reload
150
+ * starts a document with only permitted code. Waits for the save request.
151
+ * Set `false` to handle revocation yourself.
152
+ * @default true
153
+ */
154
+ reloadOnConsentRevoked?: boolean;
85
155
  scripts?: Script[];
156
+ /**
157
+ * Vendors offered for vendor-level consent outside IAB. Each sits inside a
158
+ * category; a visitor can grant the category and still turn one vendor
159
+ * off. Scripts, network rules and iframes name a vendor through `vendor`
160
+ * or `data-vendor`. Merged with vendors the backend returns and with slugs
161
+ * found on scripts and rules; presentation declared here wins.
162
+ */
163
+ vendors?: Vendor[];
86
164
  scriptLoader?: UseScriptLoaderOptions;
87
165
  networkBlocker?: UseNetworkBlockerOptions | false;
166
+ /**
167
+ * Discover and gate DOM iframes with data-category. Enabled by default.
168
+ * The blocker loads when the first gated iframe is on the page; until it
169
+ * runs, a gated iframe that arrives with a `src` consent does not allow
170
+ * is paused.
171
+ */
172
+ iframeBlocker?: UseIframeBlockerOptions | false;
173
+ /**
174
+ * Store the visitor's choice in a cookie and localStorage. On by default.
175
+ * Read once, when the provider mounts; see `storageConfig`.
176
+ */
88
177
  persistence?: boolean | UsePersistenceOptions;
89
178
  i18n?: Partial<I18nConfig>;
179
+ /** Categories to offer alongside discovered integration categories, within policy scope. */
90
180
  consentCategories?: AllConsentNames[];
91
181
  /** Per-component slot attribute overrides (shared contract with @c15t/vue). */
92
182
  components?: ReactComponentSlots;
93
183
  legalLinks?: LegalLinks;
184
+ /**
185
+ * When the deferred `<ConsentDialog />` starts loading before it opens.
186
+ *
187
+ * - `'idle'` (default): after the page's load event, in browser idle time,
188
+ * while the banner is shown or a button that opens the dialog is
189
+ * mounted, and on hover or focus of such a button. Skipped when the
190
+ * visitor has Save-Data on or a 2G-class connection.
191
+ * - `'intent'`: only on hover or focus of a button that opens the dialog.
192
+ *
193
+ * Neither loads the dialog on a visit that shows no banner and has no
194
+ * dialog trigger.
195
+ *
196
+ * @default 'idle'
197
+ */
198
+ preloadDialog?: DialogPreload;
94
199
  /**
95
200
  * Adapter package name reported by `window.c15t`.
96
201
  * @internal
97
202
  */
98
203
  __debugPkg?: string;
204
+ /**
205
+ * The code that applies a `prefetch` promise, from
206
+ * `@c15t/core/runtime/streamed-init`. Without it the provider loads that
207
+ * code once `prefetch` is a promise, so an app that never streams one
208
+ * doesn't download it. A framework root whose state is usually streamed
209
+ * (`ConsentRoot`) passes it, so the state applies as soon as it arrives
210
+ * instead of after one more request. Read once, at mount.
211
+ * @internal
212
+ */
213
+ __resolveStreamedInit?: ResolveStreamedInit;
214
+ /**
215
+ * `preloadScriptLoaderWith` from
216
+ * `@c15t/core/runtime/script-loader-preload`. With it the runtime starts
217
+ * the script loader's download during the first render when consent
218
+ * already lets a script run, instead of from the mount effect. A
219
+ * framework root whose state usually holds a returning visitor's choice
220
+ * (`ConsentRoot`) passes it; without it the provider ships none of that
221
+ * decision. Read once, at mount.
222
+ * @internal
223
+ */
224
+ __preloadScriptLoader?: (load: () => Promise<unknown>) => ConsentRuntimeModules['preloadScriptLoader'];
99
225
  }
100
226
  /**
101
227
  * Options accepted when an external runtime supplies the kernel.
@@ -104,8 +230,19 @@ export interface ConsentProviderOptions extends Pick<ReactUIOptions, 'colorSchem
104
230
  * Everything the component tree still owns — theme, slots, legal links —
105
231
  * is unchanged.
106
232
  */
107
- export type ExternalRuntimeProviderOptions = Omit<ConsentProviderOptions, 'mode'> & {
233
+ export type ExternalRuntimeProviderOptions = Omit<ConsentProviderOptions, 'callbacks' | 'mode' | 'vendors'> & {
108
234
  mode?: ConsentProviderOptions['mode'];
235
+ /**
236
+ * Not accepted here: the runtime owner declares vendors through
237
+ * `createConsentRuntime({ vendors })`, and the kernel carries them.
238
+ */
239
+ vendors?: never;
240
+ /**
241
+ * Not accepted here: the runtime owner passes callbacks to
242
+ * `createConsentRuntime({ callbacks })`, and the runtime runs them.
243
+ * Passing them anyway logs a warning in development.
244
+ */
245
+ callbacks?: never;
109
246
  };
110
247
  /** The provider builds and owns its own kernel. */
111
248
  export interface OwnedRuntimeProviderProps {
@@ -122,23 +259,27 @@ export type ConsentProviderProps = OwnedRuntimeProviderProps | ExternalRuntimePr
122
259
  /**
123
260
  * v3 ConsentProvider.
124
261
  *
125
- * Retains the enabled kernel while disabled mode uses a separate permissive
126
- * kernel, so toggling enabled preserves recorded choices. Provides the active
127
- * kernel via context and wires the curated v2-like options surface to v3
128
- * modules. It does not mirror the
129
- * snapshot into React state; selector hooks still subscribe directly to
130
- * the kernel through `useSyncExternalStore`.
262
+ * Builds one consent runtime (`createConsentProviderRuntime`) per mounted
263
+ * provider and renders its kernel: the kernel goes into context, and
264
+ * selector hooks subscribe to it through `useSyncExternalStore`. New
265
+ * options reach the runtime through `update()`, which applies only what
266
+ * changed; `mode`, `i18n`, `experiment`, `prefetch`, `persistence`,
267
+ * `storageConfig` and `clearOnRevocation` are read once. While `enabled` is
268
+ * `false` the runtime renders a separate permissive kernel, so toggling it
269
+ * keeps the visitor's records.
131
270
  *
132
271
  * Pass `runtime` to render a runtime someone else created. The provider
133
- * then borrows its kernel and mounts none of the side-effecting modules —
134
- * no second `init()`, no second persistence handle, no second `window.c15t`
135
- * — and does not dispose it on unmount.
272
+ * then borrows its kernel and starts nothing — no second `init()`, no
273
+ * second persistence handle, no second `window.c15t` — and does not
274
+ * dispose it on unmount. Handing it a different runtime switches the tree
275
+ * to that runtime's kernel; switching between a borrowed runtime and a
276
+ * provider-built one still needs a remount.
136
277
  *
137
278
  * @example
138
279
  * ```tsx
139
280
  * import { createConsentRuntime } from '@c15t/core/runtime';
140
281
  *
141
- * const runtime = createConsentRuntime({ mode: hosted({ url: '/api/c15t' }) });
282
+ * const runtime = createConsentRuntime({ mode: hosted({ backendURL: '/api/c15t' }) });
142
283
  * runtime.start();
143
284
  *
144
285
  * <ConsentProvider runtime={runtime} options={{ theme }}>
@@ -1,5 +1,5 @@
1
1
  import type { SSRInitialData } from '@c15t/core';
2
- import type { FetchSSRDataOptions } from './types';
2
+ import type { FetchSSRDataOptions } from './types.js';
3
3
  /**
4
4
  * Fetches initial consent data on the server for SSR hydration.
5
5
  *
@@ -1,5 +1,10 @@
1
- declare const FORWARDED_HEADERS: readonly ["x-c15t-country", "cf-ipcountry", "x-vercel-ip-country", "x-amz-cf-ipcountry", "x-country-code", "x-country", "x-c15t-region", "cf-region-code", "x-vercel-ip-country-region", "x-region-code", "accept-language", "x-c15t-gpc", "sec-gpc", "x-c15t-version", "user-agent", "x-forwarded-host", "x-forwarded-for", "purpose", "sec-purpose", "next-router-prefetch", "x-middleware-prefetch"];
2
- type ForwardedHeader = (typeof FORWARDED_HEADERS)[number];
1
+ declare const FORWARDED_HEADERS: readonly ["x-c15t-country", "cf-ipcountry", "x-vercel-ip-country", "x-amz-cf-ipcountry", "x-country-code", "x-country", "x-c15t-region", "cf-region-code", "x-vercel-ip-country-region", "x-region-code", "accept-language", "x-c15t-gpc", "sec-gpc", "x-c15t-version", "user-agent", "x-forwarded-for", "purpose", "sec-purpose", "next-router-prefetch", "x-middleware-prefetch"];
2
+ /**
3
+ * Forwarding headers a client can set to name a host or scheme. Passed to
4
+ * the backend only when the app trusts them.
5
+ */
6
+ export declare const CLIENT_FORWARDING_HEADERS: readonly ['forwarded', 'x-forwarded-host', 'x-forwarded-proto'];
7
+ type ForwardedHeader = (typeof FORWARDED_HEADERS)[number] | (typeof CLIENT_FORWARDING_HEADERS)[number];
3
8
  type RelevantHeaders = Partial<Record<ForwardedHeader, string>>;
4
9
  /**
5
10
  * Extracts relevant headers for consent management from the request headers.
@@ -12,10 +17,13 @@ type RelevantHeaders = Partial<Record<ForwardedHeader, string>>;
12
17
  * The extracted headers include:
13
18
  * - Country headers (cf-ipcountry, x-vercel-ip-country, etc.)
14
19
  * - Region headers (x-vercel-ip-country-region, x-region-code)
15
- * - Standard headers (accept-language, user-agent, x-forwarded-*)
20
+ * - Standard headers (accept-language, user-agent, x-forwarded-for)
16
21
  * - Prefetch headers (purpose, sec-purpose, next-router-prefetch, x-middleware-prefetch)
17
22
  *
18
23
  * @param headersList - The Headers object from the incoming request
24
+ * @param options - `trustForwardedHeaders` also copies `forwarded`,
25
+ * `x-forwarded-host` and `x-forwarded-proto`, which any client can send.
26
+ * Leave it off unless a proxy you control sets them and drops incoming ones.
19
27
  * @returns An object containing the relevant headers for consent management
20
28
  *
21
29
  * @example
@@ -28,5 +36,7 @@ type RelevantHeaders = Partial<Record<ForwardedHeader, string>>;
28
36
  *
29
37
  * @public
30
38
  */
31
- export declare const extractRelevantHeaders: (headersList: Headers) => RelevantHeaders;
39
+ export declare const extractRelevantHeaders: (headersList: Headers, options?: {
40
+ trustForwardedHeaders?: boolean;
41
+ }) => RelevantHeaders;
32
42
  export {};
@@ -24,8 +24,8 @@
24
24
  *
25
25
  * @packageDocumentation
26
26
  */
27
- export { fetchSSRData } from './fetch-ssr-data';
28
- export { extractRelevantHeaders } from './headers';
29
- export { createSSRInitCacheKey } from './init-cache-key';
30
- export { normalizeBackendURL, validateBackendURL } from './normalize-url';
31
- export type { FetchSSRDataOptions, FetchSSRDataOptionsBase, FetchSSRDataResult, } from './types';
27
+ export { fetchSSRData } from './fetch-ssr-data.js';
28
+ export { extractRelevantHeaders } from './headers.js';
29
+ export { createSSRInitCacheKey } from './init-cache-key.js';
30
+ export { normalizeBackendURL, validateBackendURL } from './normalize-url.js';
31
+ export type { FetchSSRDataOptions, FetchSSRDataOptionsBase, FetchSSRDataResult, } from './types.js';
@@ -21,16 +21,21 @@ export declare const validateBackendURL: (backendURL: string) => {
21
21
  normalizedURL: string;
22
22
  };
23
23
  /**
24
- * Normalizes a backend URL, resolving relative URLs using request headers.
24
+ * Normalizes a backend URL, resolving relative URLs against the request.
25
25
  *
26
26
  * @remarks
27
27
  * For absolute URLs, returns the URL as-is (with trailing slash trimmed).
28
- * For relative URLs, attempts to construct the full URL using:
29
- * 1. x-forwarded-proto + x-forwarded-host/host headers
30
- * 2. Referer header as fallback
28
+ * A relative URL resolves against the `host` header: over `https` for a
29
+ * domain name, and over `http` for `localhost`, an IP address or a
30
+ * single-label host. `x-forwarded-host`, `x-forwarded-proto` and `forwarded`
31
+ * are read only when `trustForwardedHeaders` is set, because any client can
32
+ * send them; the `referer` header is never used.
31
33
  *
32
34
  * @param backendURL - The backend URL (absolute or relative)
33
35
  * @param headersList - The Headers object from the incoming request
36
+ * @param options - `trustForwardedHeaders`: resolve against the request's
37
+ * forwarding headers. Set it only behind a proxy that sets them and drops
38
+ * incoming ones.
34
39
  * @returns The normalized absolute URL, or null if it cannot be determined
35
40
  *
36
41
  * @example
@@ -41,11 +46,13 @@ export declare const validateBackendURL: (backendURL: string) => {
41
46
  * normalizeBackendURL('https://api.example.com/', headers);
42
47
  * // Returns: 'https://api.example.com'
43
48
  *
44
- * // Relative URL - resolved from headers
49
+ * // Relative URL - resolved from the host header
45
50
  * normalizeBackendURL('/api/consent', headers);
46
- * // Returns: 'https://example.com/api/consent' (based on headers)
51
+ * // Returns: 'https://example.com/api/consent' (for `host: example.com`)
47
52
  * ```
48
53
  *
49
54
  * @public
50
55
  */
51
- export declare const normalizeBackendURL: (backendURL: string, headersList: Headers) => string | null;
56
+ export declare const normalizeBackendURL: (backendURL: string, headersList: Headers, options?: {
57
+ trustForwardedHeaders?: boolean;
58
+ }) => string | null;