@c15t/react 3.0.0-alpha.0 → 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 (405) hide show
  1. package/AGENTS.md +96 -69
  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 -151
  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 +35 -159
  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 +174 -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 -69
  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 -62
  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 -55
  397. package/docs/frameworks/react/styling/overview.md +0 -207
  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/upgrade-v3.md +0 -334
  402. package/readme.json +0 -48
  403. package/src/iab/styles.css +0 -11
  404. package/src/styles.css +0 -10
  405. /package/dist/components/{frame → consent-gate}/types.js +0 -0
@@ -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, 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,28 +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;
141
+ /**
142
+ * Remove configured browser data when its consent permission is revoked.
143
+ * Initial-only: remount the provider to replace its cleanup configuration.
144
+ */
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;
80
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[];
81
164
  scriptLoader?: UseScriptLoaderOptions;
82
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
+ */
83
177
  persistence?: boolean | UsePersistenceOptions;
84
178
  i18n?: Partial<I18nConfig>;
179
+ /** Categories to offer alongside discovered integration categories, within policy scope. */
85
180
  consentCategories?: AllConsentNames[];
86
181
  /** Per-component slot attribute overrides (shared contract with @c15t/vue). */
87
182
  components?: ReactComponentSlots;
88
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;
89
199
  /**
90
200
  * Adapter package name reported by `window.c15t`.
91
201
  * @internal
92
202
  */
93
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'];
94
225
  }
95
226
  /**
96
227
  * Options accepted when an external runtime supplies the kernel.
@@ -99,8 +230,19 @@ export interface ConsentProviderOptions extends Pick<ReactUIOptions, 'colorSchem
99
230
  * Everything the component tree still owns — theme, slots, legal links —
100
231
  * is unchanged.
101
232
  */
102
- export type ExternalRuntimeProviderOptions = Omit<ConsentProviderOptions, 'mode'> & {
233
+ export type ExternalRuntimeProviderOptions = Omit<ConsentProviderOptions, 'callbacks' | 'mode' | 'vendors'> & {
103
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;
104
246
  };
105
247
  /** The provider builds and owns its own kernel. */
106
248
  export interface OwnedRuntimeProviderProps {
@@ -117,23 +259,27 @@ export type ConsentProviderProps = OwnedRuntimeProviderProps | ExternalRuntimePr
117
259
  /**
118
260
  * v3 ConsentProvider.
119
261
  *
120
- * Retains the enabled kernel while disabled mode uses a separate permissive
121
- * kernel, so toggling enabled preserves recorded choices. Provides the active
122
- * kernel via context and wires the curated v2-like options surface to v3
123
- * modules. It does not mirror the
124
- * snapshot into React state; selector hooks still subscribe directly to
125
- * 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.
126
270
  *
127
271
  * Pass `runtime` to render a runtime someone else created. The provider
128
- * then borrows its kernel and mounts none of the side-effecting modules —
129
- * no second `init()`, no second persistence handle, no second `window.c15t`
130
- * — 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.
131
277
  *
132
278
  * @example
133
279
  * ```tsx
134
280
  * import { createConsentRuntime } from '@c15t/core/runtime';
135
281
  *
136
- * const runtime = createConsentRuntime({ mode: hosted({ url: '/api/c15t' }) });
282
+ * const runtime = createConsentRuntime({ mode: hosted({ backendURL: '/api/c15t' }) });
137
283
  * runtime.start();
138
284
  *
139
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;
@@ -12,9 +12,20 @@ import type { Overrides, SSRInitialData } from '@c15t/core';
12
12
  export interface FetchSSRDataOptionsBase {
13
13
  /**
14
14
  * The backend URL to fetch consent data from.
15
- * Can be absolute (https://...) or relative (/api/consent).
15
+ * Can be absolute (https://...) or relative (/api/consent). A relative
16
+ * URL resolves against the request's `host` header.
16
17
  */
17
18
  backendURL: string;
19
+ /**
20
+ * Resolve a relative `backendURL` against the request's `forwarded`,
21
+ * `x-forwarded-host` and `x-forwarded-proto` headers instead of `host`.
22
+ * Any client can send those headers, so set this only behind a proxy
23
+ * that sets them and drops incoming ones. Also forwards those three
24
+ * headers to the backend, which is skipped otherwise.
25
+ *
26
+ * @default false
27
+ */
28
+ trustForwardedHeaders?: boolean;
18
29
  /**
19
30
  * Optional overrides for geo-location.
20
31
  */
@@ -1,6 +1,6 @@
1
1
  import type { ReactNode } from 'react';
2
- import type { ThemeContextValue } from './context/theme-context';
3
- import type { V3UIConfigValue } from './ui-config-context';
2
+ import type { ThemeContextValue } from './context/theme-context.js';
3
+ import type { V3UIConfigValue } from './ui-config-context.js';
4
4
  interface V3ThemeProviderProps {
5
5
  themeConfig: ThemeContextValue;
6
6
  uiConfig: V3UIConfigValue;
@@ -0,0 +1,36 @@
1
+ import type { HostedModeFactory, HostedModeOptions } from '@c15t/core';
2
+ /** Options for {@link hosted}. `backendURL` defaults to the build's. */
3
+ export type HostedOptions = Omit<HostedModeOptions, 'backendURL'> & {
4
+ /**
5
+ * Backend URL, relative (`/api/c15t`) or absolute. Defaults to the URL
6
+ * `consentManifest()` from `c15t/build` read from
7
+ * `VITE_C15T_BACKEND_URL` or `VITE_INTH_PROJECT_URL`.
8
+ */
9
+ backendURL?: string;
10
+ };
11
+ /**
12
+ * Build a hosted factory, taking the backend URL from the build when the
13
+ * options name none.
14
+ *
15
+ * @param options - The page's options.
16
+ * @param buildBackendURL - The backend URL the build read, if any.
17
+ * @returns A hosted transport factory.
18
+ * @throws {Error} When neither names a backend URL.
19
+ * @internal
20
+ */
21
+ export declare const hostedWithBuild: (options: HostedOptions, buildBackendURL: string | undefined) => HostedModeFactory;
22
+ /**
23
+ * Ask the backend's `/init` for every visitor's policy.
24
+ *
25
+ * @param options - Backend URL, init headers and request overrides.
26
+ * @returns A transport factory for the provider's `mode`, carrying its
27
+ * options.
28
+ * @throws {Error} When no backend URL is passed and the build set none.
29
+ * @example
30
+ * ```tsx
31
+ * import { ConsentProvider, hosted } from 'c15t/react';
32
+ *
33
+ * <ConsentProvider options={{ mode: hosted() }}>{children}</ConsentProvider>;
34
+ * ```
35
+ */
36
+ export declare const hosted: (options?: HostedOptions) => HostedModeFactory;
@@ -0,0 +1,48 @@
1
+ import type { BrowserManifestModeFactory, BrowserManifestOptions } from '@c15t/core/transports/manifest-browser';
2
+ /**
3
+ * Manifest mode for the React provider: core's browser resolver, with the
4
+ * policy and backend URL the build integration downloaded as defaults.
5
+ */
6
+ import type { ConsentManifest } from '@c15t/schema/types';
7
+ /** What a build integration downloaded, as `@c15t/core/generated` exports it. */
8
+ export interface BuildOutput {
9
+ backendURL?: string;
10
+ snapshot?: ConsentManifest;
11
+ }
12
+ /**
13
+ * Fill the options the page left out from the build: the backend URL that
14
+ * saves go to, and the snapshot unless the page passed one, a
15
+ * `manifestURL`, or `source: 'runtime'`.
16
+ *
17
+ * @param options - The page's options.
18
+ * @param build - What the build downloaded.
19
+ * @returns The options `manifest()` resolves with.
20
+ * @internal
21
+ */
22
+ export declare const withBuildDefaults: (options: BrowserManifestOptions, build: BuildOutput) => BrowserManifestOptions;
23
+ /**
24
+ * Resolve the policy in the browser from the backend's consent manifest.
25
+ *
26
+ * Without options it uses what `consentManifest()` from `c15t/build`
27
+ * downloaded: the snapshot and the backend URL from
28
+ * `VITE_C15T_BACKEND_URL` or `VITE_INTH_PROJECT_URL`, both served as
29
+ * `c15t/generated`. Without a
30
+ * snapshot, such as in dev after a failed fetch, it fetches
31
+ * `${backendURL}/manifest` at runtime. Saves go to the backend either way.
32
+ * With `manifestURL` or `source: 'runtime'`, also pass `source: 'runtime'`
33
+ * to `consentManifest()`, so the build downloads no snapshot.
34
+ *
35
+ * @param options - Overrides: your own `snapshot`, `source: 'runtime'`, a
36
+ * `manifestURL`, a `backendURL`, or the visitor's location as `inputs`.
37
+ * @returns A transport factory for the provider's `mode`, carrying its
38
+ * options.
39
+ * @throws {Error} When no snapshot, manifest URL or backend URL is known.
40
+ * @example
41
+ * ```tsx
42
+ * import { ConsentProvider, manifest } from 'c15t/react';
43
+ *
44
+ * <ConsentProvider options={{ mode: manifest() }}>{children}</ConsentProvider>;
45
+ * ```
46
+ */
47
+ export declare const manifest: (options?: BrowserManifestOptions) => BrowserManifestModeFactory;
48
+ export type { BrowserManifestModeFactory, BrowserManifestOptions as ManifestModeOptions, } from '@c15t/core/transports/manifest-browser';