@c15t/nextjs 2.2.0 → 3.0.0-alpha.0

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 (220) hide show
  1. package/AGENTS.md +102 -142
  2. package/README.md +4 -4
  3. package/dist/api.js +1 -0
  4. package/dist/config.js +1 -0
  5. package/dist/devtools.js +2 -0
  6. package/dist/headers.js +1 -0
  7. package/dist/iab/styles.css +1 -1
  8. package/dist/iab/styles.tw3.css +133 -19
  9. package/dist/index.js +1 -1
  10. package/dist/middleware.js +1 -0
  11. package/dist/node-bridge.js +1 -0
  12. package/dist/pages.js +1 -0
  13. package/dist/proxy.js +1 -0
  14. package/dist/root.js +2 -0
  15. package/dist/server.js +1 -0
  16. package/dist/static.js +1 -0
  17. package/dist/styles.css +1 -1
  18. package/dist/styles.tw3.css +173 -29
  19. package/dist/version.js +1 -1
  20. package/dist-types/api.d.ts +88 -0
  21. package/dist-types/config.d.ts +110 -0
  22. package/dist-types/devtools.d.ts +1 -0
  23. package/dist-types/headers.d.ts +4 -0
  24. package/dist-types/index.d.ts +28 -10
  25. package/dist-types/middleware.d.ts +15 -0
  26. package/dist-types/node-bridge.d.ts +57 -0
  27. package/dist-types/pages.d.ts +88 -0
  28. package/dist-types/proxy.d.ts +34 -0
  29. package/dist-types/root.d.ts +86 -0
  30. package/dist-types/server.d.ts +164 -0
  31. package/dist-types/static.d.ts +42 -0
  32. package/dist-types/types.d.ts +5 -36
  33. package/dist-types/version.d.ts +1 -1
  34. package/docs/README.md +102 -142
  35. package/docs/assets/v3/brand-bar.png +0 -0
  36. package/docs/assets/v3/brand-card.png +0 -0
  37. package/docs/assets/v3/choice-wall.png +0 -0
  38. package/docs/assets/v3/mobile-card.png +0 -0
  39. package/docs/assets/v3/preferences.png +0 -0
  40. package/docs/customization/overview.md +45 -0
  41. package/docs/customization/recipes.md +79 -0
  42. package/docs/customization/slots.md +55 -0
  43. package/docs/customization/tokens.md +76 -0
  44. package/docs/customization/translations.md +49 -0
  45. package/docs/frameworks/next/api-reference/data-fetching.md +416 -0
  46. package/docs/frameworks/next/app-router.md +403 -0
  47. package/docs/frameworks/next/client-side.md +118 -0
  48. package/docs/frameworks/next/components/consent-banner.md +251 -211
  49. package/docs/frameworks/next/components/consent-dialog-link.md +96 -35
  50. package/docs/frameworks/next/components/consent-dialog-trigger.md +74 -149
  51. package/docs/frameworks/next/components/consent-dialog.md +189 -134
  52. package/docs/frameworks/next/components/consent-manager-provider.md +60 -318
  53. package/docs/frameworks/next/components/consent-widget.md +172 -114
  54. package/docs/frameworks/next/components/dev-tools.md +199 -40
  55. package/docs/frameworks/next/components/frame.md +137 -42
  56. package/docs/frameworks/next/concepts/consent-categories.md +24 -89
  57. package/docs/frameworks/next/concepts/policy-presets.md +142 -0
  58. package/docs/frameworks/next/content-security-policy.md +189 -0
  59. package/docs/frameworks/next/data-fetching.md +74 -0
  60. package/docs/frameworks/next/geography-headers.md +251 -0
  61. package/docs/frameworks/next/headless.md +95 -185
  62. package/docs/frameworks/next/hooks/use-consent-manager/overview.md +42 -163
  63. package/docs/frameworks/next/iab/overview.md +37 -107
  64. package/docs/frameworks/next/optimization.md +158 -194
  65. package/docs/frameworks/next/pages-router.md +296 -0
  66. package/docs/frameworks/next/quickstart.md +31 -132
  67. package/docs/frameworks/next/script-loader.md +134 -467
  68. package/docs/frameworks/next/server-side.md +97 -130
  69. package/docs/frameworks/next/static-export.md +164 -0
  70. package/docs/frameworks/next/styling/overview.md +166 -250
  71. package/docs/frameworks/next/troubleshooting.md +134 -144
  72. package/docs/guides/consent-state.md +60 -0
  73. package/docs/guides/data-fetching.md +163 -0
  74. package/docs/guides/deployment-modes.md +63 -0
  75. package/docs/guides/troubleshooting.md +68 -0
  76. package/docs/guides/verify-consent.md +62 -0
  77. package/docs/integrations/adobe-analytics.md +239 -105
  78. package/docs/integrations/ahrefs-analytics.md +238 -104
  79. package/docs/integrations/amplitude.md +219 -157
  80. package/docs/integrations/building-integrations.md +32 -224
  81. package/docs/integrations/clearbit.md +247 -86
  82. package/docs/integrations/cloudflare-web-analytics.md +250 -84
  83. package/docs/integrations/crisp.md +251 -97
  84. package/docs/integrations/databuddy.md +259 -153
  85. package/docs/integrations/fathom-analytics.md +239 -96
  86. package/docs/integrations/google-maps.md +328 -207
  87. package/docs/integrations/google-tag-manager.md +248 -96
  88. package/docs/integrations/google-tag.md +261 -90
  89. package/docs/integrations/heap.md +222 -149
  90. package/docs/integrations/hightouch.md +225 -131
  91. package/docs/integrations/hotjar.md +239 -90
  92. package/docs/integrations/intercom.md +239 -98
  93. package/docs/integrations/linkedin-insights.md +243 -113
  94. package/docs/integrations/logrocket.md +241 -123
  95. package/docs/integrations/matomo-analytics.md +256 -111
  96. package/docs/integrations/meta-pixel.md +197 -324
  97. package/docs/integrations/microsoft-clarity.md +233 -114
  98. package/docs/integrations/microsoft-uet.md +245 -110
  99. package/docs/integrations/mixpanel-analytics.md +252 -87
  100. package/docs/integrations/openai-pixel.md +441 -0
  101. package/docs/integrations/overview.md +95 -133
  102. package/docs/integrations/pirsch.md +249 -96
  103. package/docs/integrations/plausible-analytics.md +241 -100
  104. package/docs/integrations/posthog.md +353 -214
  105. package/docs/integrations/promptwatch.md +251 -81
  106. package/docs/integrations/reddit-pixel.md +226 -173
  107. package/docs/integrations/rudderstack.md +244 -187
  108. package/docs/integrations/rybbit-analytics.md +244 -91
  109. package/docs/integrations/segment.md +238 -92
  110. package/docs/integrations/snapchat-pixel.md +240 -110
  111. package/docs/integrations/tiktok-pixel.md +249 -81
  112. package/docs/integrations/umami-analytics.md +242 -95
  113. package/docs/integrations/vercel-analytics.md +242 -90
  114. package/docs/integrations/x-pixel.md +238 -104
  115. package/docs/integrations/youtube.md +354 -142
  116. package/docs/upgrade-v3.md +334 -0
  117. package/iab/styles.css +1 -1
  118. package/iab/styles.tw3.css +1 -1
  119. package/package.json +106 -65
  120. package/readme.json +3 -3
  121. package/src/iab/styles.css +1 -1
  122. package/src/iab/styles.tw3.css +1 -1
  123. package/src/styles.css +1 -1
  124. package/src/styles.tw3.css +1 -1
  125. package/styles.css +1 -1
  126. package/styles.tw3.css +1 -1
  127. package/client/components/consent-dialog-link.js +0 -3
  128. package/client/components/integrations.js +0 -3
  129. package/dist/components/integrations/index.cjs +0 -1
  130. package/dist/components/integrations/index.js +0 -1
  131. package/dist/headless.cjs +0 -1
  132. package/dist/index.cjs +0 -1
  133. package/dist/libs/browser-initial-data.cjs +0 -1
  134. package/dist/libs/browser-initial-data.js +0 -1
  135. package/dist/libs/initial-data.cjs +0 -1
  136. package/dist/libs/initial-data.js +0 -1
  137. package/dist/types.cjs +0 -1
  138. package/dist/version.cjs +0 -1
  139. package/dist-types/components/integrations/index.d.ts +0 -1
  140. package/dist-types/libs/browser-initial-data.d.ts +0 -9
  141. package/dist-types/libs/initial-data.d.ts +0 -33
  142. package/docs/frameworks/next/building-headless-components.md +0 -379
  143. package/docs/frameworks/next/callbacks.md +0 -186
  144. package/docs/frameworks/next/concepts/client-modes.md +0 -177
  145. package/docs/frameworks/next/concepts/consent-models.md +0 -117
  146. package/docs/frameworks/next/concepts/cookie-management.md +0 -122
  147. package/docs/frameworks/next/concepts/glossary.md +0 -24
  148. package/docs/frameworks/next/concepts/initialization-flow.md +0 -149
  149. package/docs/frameworks/next/concepts/policy-packs.md +0 -230
  150. package/docs/frameworks/next/hooks/use-color-scheme.md +0 -41
  151. package/docs/frameworks/next/hooks/use-consent-manager/checking-consent.md +0 -96
  152. package/docs/frameworks/next/hooks/use-consent-manager/location-info.md +0 -97
  153. package/docs/frameworks/next/hooks/use-consent-manager/setting-consent.md +0 -94
  154. package/docs/frameworks/next/hooks/use-draggable.md +0 -59
  155. package/docs/frameworks/next/hooks/use-focus-trap.md +0 -42
  156. package/docs/frameworks/next/hooks/use-reduced-motion.md +0 -37
  157. package/docs/frameworks/next/hooks/use-ssr-status.md +0 -32
  158. package/docs/frameworks/next/hooks/use-text-direction.md +0 -50
  159. package/docs/frameworks/next/hooks/use-translations.md +0 -55
  160. package/docs/frameworks/next/iab/consent-banner.md +0 -91
  161. package/docs/frameworks/next/iab/consent-dialog.md +0 -129
  162. package/docs/frameworks/next/iab/use-gvl-data.md +0 -21
  163. package/docs/frameworks/next/iframe-blocking.md +0 -106
  164. package/docs/frameworks/next/internationalization.md +0 -207
  165. package/docs/frameworks/next/network-blocker.md +0 -140
  166. package/docs/frameworks/next/policy-packs.md +0 -248
  167. package/docs/frameworks/next/styling/classnames.md +0 -94
  168. package/docs/frameworks/next/styling/color-scheme.md +0 -84
  169. package/docs/frameworks/next/styling/css-variables.md +0 -53
  170. package/docs/frameworks/next/styling/slots.md +0 -94
  171. package/docs/frameworks/next/styling/tailwind.md +0 -137
  172. package/docs/frameworks/next/styling/tokens.md +0 -156
  173. package/docs/shared/concepts/client-modes.md +0 -103
  174. package/docs/shared/concepts/consent-categories.md +0 -41
  175. package/docs/shared/concepts/consent-models.md +0 -72
  176. package/docs/shared/concepts/cookie-management.md +0 -88
  177. package/docs/shared/concepts/glossary.md +0 -24
  178. package/docs/shared/concepts/initialization-flow.md +0 -105
  179. package/docs/shared/concepts/policy-packs.md +0 -225
  180. package/docs/shared/react/components/consent-banner.md +0 -242
  181. package/docs/shared/react/components/consent-dialog-link.md +0 -45
  182. package/docs/shared/react/components/consent-dialog-trigger.md +0 -185
  183. package/docs/shared/react/components/consent-dialog.md +0 -119
  184. package/docs/shared/react/components/consent-manager-provider.md +0 -225
  185. package/docs/shared/react/components/consent-widget.md +0 -121
  186. package/docs/shared/react/components/dev-tools.md +0 -81
  187. package/docs/shared/react/components/frame.md +0 -52
  188. package/docs/shared/react/guides/building-headless-components.md +0 -110
  189. package/docs/shared/react/guides/callbacks.md +0 -89
  190. package/docs/shared/react/guides/headless.md +0 -31
  191. package/docs/shared/react/guides/iframe-blocking.md +0 -65
  192. package/docs/shared/react/guides/internationalization.md +0 -123
  193. package/docs/shared/react/guides/network-blocker.md +0 -72
  194. package/docs/shared/react/guides/optimization.md +0 -44
  195. package/docs/shared/react/guides/policy-packs.md +0 -173
  196. package/docs/shared/react/guides/script-loader.md +0 -311
  197. package/docs/shared/react/hooks/use-color-scheme.md +0 -31
  198. package/docs/shared/react/hooks/use-consent-manager/checking-consent.md +0 -95
  199. package/docs/shared/react/hooks/use-consent-manager/location-info.md +0 -96
  200. package/docs/shared/react/hooks/use-consent-manager/overview.md +0 -74
  201. package/docs/shared/react/hooks/use-consent-manager/setting-consent.md +0 -93
  202. package/docs/shared/react/hooks/use-draggable.md +0 -30
  203. package/docs/shared/react/hooks/use-focus-trap.md +0 -20
  204. package/docs/shared/react/hooks/use-reduced-motion.md +0 -33
  205. package/docs/shared/react/hooks/use-ssr-status.md +0 -16
  206. package/docs/shared/react/hooks/use-text-direction.md +0 -38
  207. package/docs/shared/react/hooks/use-translations.md +0 -15
  208. package/docs/shared/react/iab/consent-banner.md +0 -60
  209. package/docs/shared/react/iab/consent-dialog.md +0 -76
  210. package/docs/shared/react/iab/overview.md +0 -80
  211. package/docs/shared/react/iab/use-gvl-data.md +0 -21
  212. package/docs/shared/react/styling/classnames.md +0 -93
  213. package/docs/shared/react/styling/color-scheme.md +0 -35
  214. package/docs/shared/react/styling/css-variables.md +0 -53
  215. package/docs/shared/react/styling/overview.md +0 -261
  216. package/docs/shared/react/styling/slots.md +0 -93
  217. package/docs/shared/react/styling/stylesheet-entrypoint.md +0 -8
  218. package/docs/shared/react/styling/tailwind.md +0 -88
  219. package/docs/shared/react/styling/tokens.md +0 -155
  220. package/docs/shared/troubleshooting.md +0 -82
@@ -1,94 +0,0 @@
1
- ---
2
- title: Component Slots
3
- description: Target individual component parts with styles using the slot system
4
- - className strings or inline style objects.
5
- group: frameworks
6
- ---
7
- ## What are Slots?
8
-
9
- Slots let you target specific parts of consent components with styles. Each component is built from named slots such as `consentBannerTitle` and `consentDialogTag`.
10
-
11
- Use slots after the stock component APIs and design tokens:
12
-
13
- * If the change is semantic, prefer tokens first. For example, the stock banner footer background comes from `theme.colors.surfaceHover`.
14
- * If the component part is correct but you need a local tweak, use a slot.
15
-
16
- Common banner slot choices:
17
-
18
- * `consentBannerCard` for card radius, shadow, width, and local background treatment
19
- * `consentBannerFooter` for spacing, borders, and local footer styling
20
- * `consentBannerTitle` for title typography
21
- * `buttonPrimary` and `buttonSecondary` for shared button classes
22
-
23
- ## Using Slots
24
-
25
- Pass slot styles in the theme's `slots` object:
26
-
27
- ```tsx
28
- const theme = {
29
- slots: {
30
- consentBannerFooter: 'border-t border-black/10 px-6',
31
- consentBannerTitle: 'text-xl font-bold tracking-tight',
32
-
33
- // Object value = className + inline styles
34
- consentBannerCard: {
35
- className: 'rounded-xl shadow-lg',
36
- style: { maxWidth: '600px' },
37
- },
38
- },
39
- } satisfies Theme;
40
- ```
41
-
42
- ## Slot Style Types
43
-
44
- Each slot accepts either a `string` (treated as className) or a `SlotStyle` object:
45
-
46
- ```tsx
47
- // String: treated as className
48
- consentBannerTitle: 'my-custom-class'
49
-
50
- // Object: className + style + noStyle
51
- consentBannerFooter: {
52
- className: 'border-t border-black/10',
53
- style: { paddingBlock: '1rem' },
54
- noStyle: false, // Set true only when you want to remove this slot's default styling
55
- }
56
- ```
57
-
58
- `noStyle` on a slot is an advanced escape hatch. Start with className and style overrides first.
59
-
60
- ## Example: Style the stock banner without changing markup
61
-
62
- ```tsx
63
- const theme = {
64
- colors: {
65
- surface: '#fffdf8',
66
- surfaceHover: '#f6f3ee',
67
- },
68
- slots: {
69
- consentBannerCard: 'rounded-[28px] shadow-xl',
70
- consentBannerFooter: 'border-t border-black/10 px-6',
71
- consentBannerTitle: 'tracking-tight',
72
- },
73
- } satisfies Theme;
74
- ```
75
-
76
- ## Available Slots
77
-
78
- Use the typed API reference below for the full slot list and descriptions. It stays in sync with the actual component slot surface.
79
-
80
- ## API Reference
81
-
82
- |Property|Value|
83
- |:--|:--|
84
- |Type Name|\`ComponentSlots\`|
85
- |Source Path|\`./packages/ui/src/theme/types.ts\`|
86
-
87
- \*ExtractedTypeTable: Could not extract "ComponentSlots" from "./packages/ui/src/theme/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
88
-
89
- |Property|Value|
90
- |:--|:--|
91
- |Type Name|\`SlotStyle\`|
92
- |Source Path|\`./packages/ui/src/theme/types.ts\`|
93
-
94
- \*ExtractedTypeTable: Could not extract "SlotStyle" from "./packages/ui/src/theme/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
@@ -1,137 +0,0 @@
1
- ---
2
- title: Tailwind CSS
3
- description: Use Tailwind CSS utility classes to style consent components via
4
- the slot system.
5
- group: frameworks
6
- ---
7
- c15t works with Tailwind CSS out of the box. Use the `slots` theme option to apply Tailwind utility classes to any component part.
8
-
9
- ## Setup
10
-
11
- Import the standard c15t stylesheet once in your app-level CSS entrypoint:
12
-
13
- ```css
14
- /* React: src/index.css */
15
- @import "@c15t/react/styles.css";
16
-
17
- /* Next.js: app/globals.css */
18
- @import "@c15t/nextjs/styles.css";
19
- ```
20
-
21
- Keeping the c15t stylesheet in your global CSS entrypoint makes layer and cascade order explicit. JS/TSX side-effect imports can load in a different order across framework and Tailwind tooling, which makes style regressions harder to debug.
22
-
23
- With Tailwind v4, keep c15t at the end of the top-level `@import` block so Fumadocs, `tw-animate-css`, and other preset imports do not override c15t theme tokens.
24
-
25
- ### Tailwind v4
26
-
27
- Tailwind v4 automatically scans your source files. Import Tailwind normally, then keep the c15t stylesheet last in the top-level `@import` block so Fumadocs, `tw-animate-css`, or other preset styles load first. c15t component styles join Tailwind's `components` layer automatically, so no extra c15t-specific layer declaration is needed:
28
-
29
- ```css title="src/index.css"
30
- @import "tailwindcss";
31
- @import "tw-animate-css";
32
- @import "@c15t/react/styles.css";
33
- ```
34
-
35
- ```css title="app/globals.css"
36
- @import "tailwindcss";
37
- @import "tw-animate-css";
38
- @import "@c15t/nextjs/styles.css";
39
- ```
40
-
41
- ### Tailwind v3
42
-
43
- Import the Tailwind 3-compatible c15t stylesheet after `@tailwind components;` and before `@tailwind utilities;`:
44
-
45
- ```css title="src/index.css"
46
- @tailwind base;
47
- @tailwind components;
48
- @import "@c15t/react/styles.tw3.css";
49
- @tailwind utilities;
50
- ```
51
-
52
- ```css title="app/globals.css"
53
- @tailwind base;
54
- @tailwind components;
55
- @import "@c15t/nextjs/styles.tw3.css";
56
- @tailwind utilities;
57
- ```
58
-
59
- ## Troubleshooting: Fumadocs Overrides c15t Styles
60
-
61
- If c15t components render partially unstyled or lose their theme tokens inside a Fumadocs site, check the order of the imports in `app/globals.css`.
62
-
63
- **Cause:** Fumadocs preset imports can load after c15t and override the tokens and layer output that c15t components depend on.
64
-
65
- **Fix:** Keep `@c15t/nextjs/styles.css` at the end of the top-level `@import` block:
66
-
67
- ```css title="app/globals.css"
68
- @import "tailwindcss";
69
- @import "tw-animate-css";
70
- @import "fumadocs-ui/css/shadcn.css";
71
- @import "fumadocs-ui/css/preset.css";
72
- @import "@c15t/nextjs/styles.css";
73
- ```
74
-
75
- If you use other preset or docs-site stylesheets, apply the same rule: load them first, then import c15t last in the top-level import block.
76
-
77
- ## Using Tailwind with Slots
78
-
79
- Apply Tailwind classes via the theme's `slots` object:
80
-
81
- ```tsx
82
- import { type ReactNode } from 'react';
83
- import { type Theme, ConsentManagerProvider } from '@c15t/nextjs';
84
-
85
- const theme = {
86
- slots: {
87
- consentBanner: 'fixed bottom-0 inset-x-0 z-50',
88
- consentBannerCard: 'mx-auto max-w-2xl rounded-t-2xl bg-white p-6 shadow-2xl',
89
- consentBannerTitle: 'text-lg font-semibold text-gray-900',
90
- consentBannerDescription: 'mt-2 text-sm text-gray-600',
91
- consentBannerFooter: 'mt-4 flex flex-wrap gap-3',
92
- buttonPrimary: 'rounded-full bg-indigo-600 px-6 py-2.5 text-sm font-medium text-white hover:bg-indigo-700',
93
- buttonSecondary: 'rounded-full border border-gray-300 px-6 py-2.5 text-sm font-medium text-gray-700 hover:bg-gray-50',
94
- toggle: 'data-[state=checked]:bg-indigo-600',
95
- },
96
- } satisfies Theme;
97
-
98
- export function ConsentManager({ children }: { children: ReactNode }) {
99
- return (
100
- <ConsentManagerProvider options={{ theme, mode: 'hosted', backendURL: '/api/c15t' }}>
101
- {children}
102
- </ConsentManagerProvider>
103
- );
104
- }
105
- ```
106
-
107
- ## Dark Mode with Tailwind
108
-
109
- Combine Tailwind's dark mode with c15t's `dark` tokens:
110
-
111
- ```tsx
112
- const theme = {
113
- colors: {
114
- primary: '#6366f1',
115
- surface: '#ffffff',
116
- text: '#1f2937',
117
- },
118
- dark: {
119
- primary: '#818cf8',
120
- surface: '#1f2937',
121
- text: '#f9fafb',
122
- },
123
- slots: {
124
- consentBannerCard: 'bg-white dark:bg-gray-900 shadow-lg dark:shadow-gray-900/30',
125
- consentBannerTitle: 'text-gray-900 dark:text-gray-100',
126
- },
127
- } satisfies Theme;
128
- ```
129
-
130
- ## Optional: noStyle Mode
131
-
132
- If you want Tailwind to own all layout and visual styling, use `noStyle: true`.
133
-
134
- > ℹ️ **Info:**
135
- > When using noStyle: true with Tailwind, you're responsible for all layout and visual styling. Start with slots first, then switch to noStyle only when you need full control.
136
-
137
- For full custom markup (not just styles), see [Headless Mode](../headless).
@@ -1,156 +0,0 @@
1
- ---
2
- title: Design Tokens
3
- description: The six base token categories that control colors, typography,
4
- spacing, radius, shadows, and motion, plus optional dark-mode overrides.
5
- group: frameworks
6
- ---
7
- ## Color Tokens
8
-
9
- Color tokens define the palette for all consent components. Set `colors` for light mode and `dark` for dark mode overrides.
10
-
11
- When `textOnPrimary` is omitted, c15t derives it automatically from `primary` to keep text readable on primary-filled surfaces such as stock branding tags and buttons. Set `textOnPrimary` explicitly when you need a specific foreground color.
12
-
13
- ```tsx
14
- const theme = {
15
- colors: {
16
- primary: '#6366f1',
17
- primaryHover: '#4f46e5',
18
- surface: '#ffffff',
19
- surfaceHover: '#f9fafb',
20
- border: '#e5e7eb',
21
- borderHover: '#d1d5db',
22
- text: '#1f2937',
23
- textMuted: '#6b7280',
24
- textOnPrimary: '#ffffff',
25
- overlay: 'rgba(0, 0, 0, 0.5)',
26
- switchTrack: '#d1d5db',
27
- switchTrackActive: '#6366f1',
28
- switchThumb: '#ffffff',
29
- },
30
- dark: {
31
- primary: '#818cf8',
32
- surface: '#1f2937',
33
- text: '#f9fafb',
34
- textMuted: '#9ca3af',
35
- border: '#374151',
36
- },
37
- } satisfies Theme;
38
- ```
39
-
40
- |Property|Value|
41
- |:--|:--|
42
- |Type Name|\`ColorTokens\`|
43
- |Source Path|\`./packages/ui/src/theme/types.ts\`|
44
-
45
- \*ExtractedTypeTable: Could not extract "ColorTokens" from "./packages/ui/src/theme/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
46
-
47
- ## Typography Tokens
48
-
49
- Control font family, sizes, weights, and line heights.
50
-
51
- ```tsx
52
- const theme = {
53
- typography: {
54
- fontFamily: 'Inter, system-ui, sans-serif',
55
- fontSize: { sm: '0.875rem', base: '1rem', lg: '1.125rem' },
56
- fontWeight: { normal: 400, medium: 500, semibold: 600 },
57
- lineHeight: { tight: '1.25', normal: '1.5', relaxed: '1.75' },
58
- },
59
- } satisfies Theme;
60
- ```
61
-
62
- |Property|Value|
63
- |:--|:--|
64
- |Type Name|\`TypographyTokens\`|
65
- |Source Path|\`./packages/ui/src/theme/types.ts\`|
66
-
67
- \*ExtractedTypeTable: Could not extract "TypographyTokens" from "./packages/ui/src/theme/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
68
-
69
- ## Spacing Tokens
70
-
71
- Five-step scale for internal padding, margins, and gaps.
72
-
73
- ```tsx
74
- const theme = {
75
- spacing: {
76
- xs: '0.25rem', // 4px
77
- sm: '0.5rem', // 8px
78
- md: '1rem', // 16px
79
- lg: '1.5rem', // 24px
80
- xl: '2rem', // 32px
81
- },
82
- } satisfies Theme;
83
- ```
84
-
85
- |Property|Value|
86
- |:--|:--|
87
- |Type Name|\`SpacingTokens\`|
88
- |Source Path|\`./packages/ui/src/theme/types.ts\`|
89
-
90
- \*ExtractedTypeTable: Could not extract "SpacingTokens" from "./packages/ui/src/theme/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
91
-
92
- ## Radius Tokens
93
-
94
- Border radius scale for rounded corners.
95
-
96
- ```tsx
97
- const theme = {
98
- radius: {
99
- sm: '0.25rem', // 4px
100
- md: '0.5rem', // 8px
101
- lg: '0.75rem', // 12px
102
- full: '9999px', // Pill shape
103
- },
104
- } satisfies Theme;
105
- ```
106
-
107
- |Property|Value|
108
- |:--|:--|
109
- |Type Name|\`RadiusTokens\`|
110
- |Source Path|\`./packages/ui/src/theme/types.ts\`|
111
-
112
- \*ExtractedTypeTable: Could not extract "RadiusTokens" from "./packages/ui/src/theme/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
113
-
114
- ## Shadow Tokens
115
-
116
- Box shadow scale for depth and elevation.
117
-
118
- ```tsx
119
- const theme = {
120
- shadows: {
121
- sm: '0 1px 2px hsla(0, 0%, 0%, 0.05)',
122
- md: '0 4px 12px hsla(0, 0%, 0%, 0.08)',
123
- lg: '0 8px 24px hsla(0, 0%, 0%, 0.12)',
124
- },
125
- } satisfies Theme;
126
- ```
127
-
128
- |Property|Value|
129
- |:--|:--|
130
- |Type Name|\`ShadowTokens\`|
131
- |Source Path|\`./packages/ui/src/theme/types.ts\`|
132
-
133
- \*ExtractedTypeTable: Could not extract "ShadowTokens" from "./packages/ui/src/theme/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
134
-
135
- ## Motion Tokens
136
-
137
- Animation duration and easing presets.
138
-
139
- ```tsx
140
- const theme = {
141
- motion: {
142
- duration: { fast: '100ms', normal: '200ms', slow: '300ms' },
143
- easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
144
- easingOut: 'cubic-bezier(0.215, 0.61, 0.355, 1)',
145
- easingInOut: 'cubic-bezier(0.645, 0.045, 0.355, 1)',
146
- easingSpring: 'cubic-bezier(0.34, 1.56, 0.64, 1)',
147
- },
148
- } satisfies Theme;
149
- ```
150
-
151
- |Property|Value|
152
- |:--|:--|
153
- |Type Name|\`MotionTokens\`|
154
- |Source Path|\`./packages/ui/src/theme/types.ts\`|
155
-
156
- \*ExtractedTypeTable: Could not extract "MotionTokens" from "./packages/ui/src/theme/types.ts" using base path "/home/runner/work/c15t/c15t". Verify the path/name and that the file is included by your tsconfig.\*
@@ -1,103 +0,0 @@
1
- ---
2
- title: Client Modes
3
- description: Reference page for client modes.
4
- group: reference
5
- ---
6
- c15t supports three client modes that determine how consent data is stored and synchronized. Choose the mode that matches your infrastructure:
7
-
8
- * **Hosted mode** - Recommended for production. Backend-backed consent with geolocation, centralized policy resolution, audit history, and offline fallback.
9
- * **Offline mode** - Browser-only storage with no network requests. Best for local development, demos, static deployments, or controlled fallback scenarios.
10
- * **Custom mode** - Bring your own backend with custom endpoint handlers
11
-
12
- > ⚠️ **Warning:**
13
- > If you need durable consent records, server-side enforcement, or automatic jurisdiction detection, use hosted mode. Offline mode cannot provide those guarantees because consent lives only in the browser.
14
-
15
- <span id="c15t-mode" />
16
-
17
- ## Hosted Mode (Recommended)
18
-
19
- The default mode. Connects to a c15t backend for full consent lifecycle management. We recommend using [inth.com](https://inth.com) for a fully managed experience, but you can [self-host](/docs/self-host) as well.
20
-
21
- > ℹ️ **Info:**
22
- > mode: 'hosted' is the preferred value. The legacy alias mode: 'c15t' is still supported for backward compatibility.
23
-
24
- **What happens:**
25
-
26
- 1. On page load, the client calls `/init` to fetch geolocation, jurisdiction, localized translation strings
27
- 2. When the user grants or changes consent, it is saved locally before being synced to the backend.
28
- 3. If the backend is unreachable, it falls back to Offline mode and re-syncs with the backend when it's available
29
-
30
- **Configuration:**
31
-
32
- * `backendURL` (required) - API endpoint path
33
-
34
- **Why it is the default for production:**
35
-
36
- * The backend stays the source of truth for policy, translations, and jurisdiction logic
37
- * Consent decisions can be stored beyond the current browser session for audit and support workflows
38
- * Server-side systems can preload consent-aware behavior instead of waiting for client-only storage
39
- * If the backend is temporarily unavailable, c15t can fall back locally and re-sync later
40
-
41
- **Best for:** Production apps that need geolocation-based jurisdiction detection, consent record storage, and compliance audit trails.
42
-
43
- ## Offline Mode
44
-
45
- No network requests. Consent is stored entirely in the browser using localStorage and cookies.
46
-
47
- **What happens:**
48
-
49
- 1. Default jurisdiction is GDPR unless manually set via `overrides`
50
- 2. Consent preferences persist locally only
51
- 3. No server-side consent records or analytics
52
-
53
- > ℹ️ **Info:**
54
- > Important: Offline mode still stores consent locally (cookie + localStorage). It only skips backend storage and sync.
55
-
56
- ### Consequences of Browser-Only Storage
57
-
58
- If consent is not stored at all (for example, storage is blocked or frequently cleared):
59
-
60
- * Users are treated as new visitors and must re-consent repeatedly
61
- * Preferences are lost across browser resets, private sessions, and device changes
62
- * You have no reliable audit evidence to prove prior consent choices
63
- * Support and compliance teams have no centralized visibility into consent history by default
64
- * Server-side systems cannot apply prior consent decisions before client initialization
65
-
66
- **Trade-offs:**
67
-
68
- * No automatic geolocation or jurisdiction detection
69
- * No consent audit trail
70
- * No centralized policy or translation updates without shipping frontend changes
71
- * No cross-device sync
72
- * No server-side visibility before client initialization
73
- * Works without any backend infrastructure
74
-
75
- **Best for:** Local development, Storybook/static demos, resilience fallback, or simpler sites that explicitly accept browser-only consent storage.
76
-
77
- ## Custom Mode
78
-
79
- Bring your own backend. You provide handler functions for each consent endpoint, and c15t calls them instead of making HTTP requests.
80
-
81
- **What happens:**
82
-
83
- 1. On page load, the client calls your endpoint handler to fetch geolocation, jurisdiction, localized translation strings
84
- 2. When the user grants or changes consent, it is saved locally before being synced to the backend.
85
- 3. If one of your handlers fails, c15t returns a handler error and keeps local consent state, but automatic offline fallback and retry queue behavior is not provided for custom handlers by default
86
-
87
- This lets you integrate c15t with any existing API - your CRM, your own consent database, or a third-party compliance service.
88
-
89
- **Best for:** Teams with existing consent infrastructure that want c15t's frontend without its backend.
90
-
91
- ## Choosing a Mode
92
-
93
- |Feature|Hosted|Offline|Custom|
94
- |--|--|--|--|
95
- |Geolocation|Automatic|Manual via overrides|Your implementation|
96
- |Policy source of truth|Backend-managed|Bundled into the frontend|Your implementation|
97
- |Consent sync|API|Local only|Your implementation|
98
- |Audit trail|Backend records|Not available|Your implementation|
99
- |Server-side consent awareness|Supported|Not available|Your implementation|
100
- |SSR data|Supported|Not available|Your implementation|
101
- |Analytics|Built-in|Not available|Your implementation|
102
- |Infrastructure|c15t backend|None|Your backend|
103
- |Setup effort|Minimal|Zero|Moderate|
@@ -1,41 +0,0 @@
1
- ---
2
- title: Consent Categories
3
- description: Reference page for consent categories.
4
- group: reference
5
- ---
6
- c15t organizes tracking technologies into five consent categories that align with GDPR and ePrivacy Directive requirements. Rather than asking users to approve or deny individual cookies or scripts, each category groups related tracking purposes together so users can make meaningful, informed choices about how their data is used.
7
-
8
- > ℹ️ **Info:**
9
- > Why categories, not cookie lists? Many consent banners list individual cookie names like \_ga, \_gid, or \_fbp. This is counterproductive:Technical names are meaningless to users — nobody knows what \_gid does by reading its name.Information overload drives "accept all" — a wall of cookie names pushes users toward dismissing the banner as fast as possible, which is the opposite of informed consent.Purpose is what matters — privacy regulations (GDPR, ePrivacy) require clear information about the purposes of data processing, not a cookie-by-cookie inventory.Cookie lists go stale — third-party scripts change their cookie names across versions, creating a maintenance burden that provides no real transparency.c15t's category-based approach — "measurement", "marketing", "experience" — communicates purpose directly. Users understand why data is collected, not how it is stored.
10
-
11
- ## The Five Categories
12
-
13
- |Category|Default|Toggleable|Description|
14
- |--|--|--|--|
15
- |`necessary`|`true`|No|Strictly necessary to operate or deliver the service|
16
- |`functionality`|`false`|Yes|Basic interactions and functionalities|
17
- |`experience`|`false`|Yes|Improve quality of user experience|
18
- |`measurement`|`false`|Yes|Measure traffic and analyze behavior|
19
- |`marketing`|`false`|Yes|Deliver personalized ads or marketing content|
20
-
21
- The `necessary` category has `disabled: true` set internally, which prevents the user from toggling it off in the consent UI. All other categories can be freely toggled by the user.
22
-
23
- Note that all categories except `necessary` have `display: false` by default. A category appears in the consent UI only if you include it in `consentCategories`. Categories not listed are hidden from the UI, but they still exist in consent state and may be affected by model-level behavior (for example, auto-grant in `opt-out` or `null` model flows).
24
-
25
- ## Configuring Categories
26
-
27
- The `consentCategories` array controls which consent categories are presented to the user in the consent UI. Only categories you list in this array will appear as toggleable options in the consent banner or modal.
28
-
29
- The `necessary` category is always implicitly included even if you do not add it to the array. You never need to worry about accidentally omitting it -- c15t ensures it is always present and always enabled.
30
-
31
- For example, if you set:
32
-
33
- ```
34
- consentCategories: ['necessary', 'measurement', 'marketing']
35
- ```
36
-
37
- then only those three categories will show toggles in the consent UI. The `functionality` and `experience` categories will not appear as user-configurable toggles.
38
-
39
- In `opt-in`/`iab` flows, hidden categories usually remain `false` unless you explicitly set them. In `opt-out`/`null` flows, categories may be auto-granted even when hidden.
40
-
41
- This gives you precise control over which consent choices to present to your users. A simple blog that only runs an analytics script might only need `measurement`. A media site with ad integrations would include `marketing`. A SaaS application with personalization features might add `experience` and `functionality` as well. You choose what is relevant to your site and c15t handles the rest - storing consent state, exposing it through hooks, and ensuring the right categories are active based on the user's choices.
@@ -1,72 +0,0 @@
1
- ---
2
- title: Consent Models
3
- description: Reference page for consent models.
4
- group: reference
5
- ---
6
- c15t supports four consent models that control how consent defaults, banner visibility, and category gating behave:
7
-
8
- |Model|Philosophy|Banner|Categories default to|
9
- |--|--|--|--|
10
- |`opt-in`|Explicit consent required|Blocking banner|`false` (except `necessary`)|
11
- |`opt-out`|Processing allowed by default|Non-blocking notice|`true` (all granted)|
12
- |`iab`|IAB TCF 2.3 for programmatic ads|TCF banner|Managed by TCF framework|
13
- |`null`|No regulation detected|No banner|`true` (all auto-granted)|
14
-
15
- There are two ways c15t determines which model applies:
16
-
17
- 1. **Policy packs** (recommended) — you explicitly set the model per region in a `PolicyConfig`. This gives you full control over which regions get which model. See [Policy Packs](/docs/frameworks/react/concepts/policy-packs).
18
-
19
- 2. **Automatic jurisdiction mapping** (legacy default) — when no policy pack is configured, c15t detects the visitor's jurisdiction via geolocation and maps it to a model using the table below. This still works but gives you less control over categories, UI, and scope.
20
-
21
- > ℹ️ **Info:**
22
- > When using policy packs, the consent.model field in each policy directly sets the model — the automatic jurisdiction mapping is bypassed for that request.
23
-
24
- ## The Four Models
25
-
26
- ### Opt-in
27
-
28
- The strictest consent model, used for GDPR and similar regulations that require explicit, affirmative consent before any non-essential data processing occurs. All consent categories except `necessary` default to `false`. A consent banner must be shown before any tracking scripts load.
29
-
30
- Applies to: EU (GDPR), UK (UK GDPR), Switzerland, Brazil (LGPD), Japan (APPI), South Korea (PIPA), Quebec (Law 25). Also the fallback for unknown jurisdiction codes.
31
-
32
- ### Opt-out
33
-
34
- Used for CCPA-style regulations where data processing is permitted by default until the user exercises their right to opt out. All consent categories default to `true`. A blocking banner is not required — the typical pattern is a non-intrusive notice or footer link.
35
-
36
- Applies to: California (CCPA), Canada (PIPEDA), Australia.
37
-
38
- When the policy has `consent.gpc: true`, the browser's Global Privacy Control signal (`Sec-GPC: 1` or `navigator.globalPrivacyControl`) is respected — `marketing` and `measurement` are denied while other categories remain granted. The built-in California presets enable this by default. See [Policy Packs — GPC](/docs/frameworks/react/concepts/policy-packs#gpc) for details.
39
-
40
- ### IAB
41
-
42
- IAB Transparency and Consent Framework (TCF) 2.3 mode for programmatic advertising compliance. Only activates when two conditions are met: the jurisdiction is `GDPR` or `UK_GDPR`, and `iab.enabled` is `true` in your configuration.
43
-
44
- When active, IAB mode generates TC strings, registers the `__tcfapi` CMP API, and works with the Global Vendor List (GVL) for machine-readable consent signals. If `iab.enabled` is not set, GDPR jurisdictions fall back to standard opt-in.
45
-
46
- ### null
47
-
48
- Returned when no jurisdiction is detected (`NONE` or `null`). No banner is displayed. On first visit, all categories are auto-granted.
49
-
50
- ## Jurisdiction Mapping
51
-
52
- When no policy pack is configured, c15t maps jurisdictions to models automatically:
53
-
54
- |Jurisdiction Code|Region|Consent Model|
55
- |--|--|--|
56
- |`GDPR`|European Union|opt-in|
57
- |`UK_GDPR`|United Kingdom|opt-in|
58
- |`CH`|Switzerland|opt-in|
59
- |`BR`|Brazil (LGPD)|opt-in|
60
- |`APPI`|Japan|opt-in|
61
- |`PIPA`|South Korea|opt-in|
62
- |`PIPEDA`|Canada (excl. Quebec)|opt-out|
63
- |`QC_LAW25`|Quebec, Canada|opt-in|
64
- |`CCPA`|California, USA|opt-out|
65
- |`AU`|Australia|opt-out|
66
- |`NONE`|No jurisdiction|null|
67
- |*(unknown)*|Any other|opt-in|
68
-
69
- **IAB override:** If `iab.enabled: true` and the jurisdiction is `GDPR` or `UK_GDPR`, the model becomes `'iab'` instead of `'opt-in'`. This override only applies to those two jurisdictions.
70
-
71
- > ℹ️ **Info:**
72
- > With policy packs, you set the model explicitly per policy — the automatic mapping above is only used as a fallback when no policy pack is configured, or for non-policy-pack features like auto-granting in opt-out jurisdictions.