@c15t/nextjs 2.2.1 → 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
@@ -0,0 +1,296 @@
1
+ ---
2
+ title: Pages Router
3
+ description: Set up Pages Router with Inth, cached manifests and consent-gated scripts.
4
+ group: frameworks
5
+ ---
6
+
7
+ ## Before you start
8
+
9
+ This guide uses [Inth](https://inth.com) with cached manifests. Your Next.js
10
+ server reuses public policy data and resolves consent for each visitor. The
11
+ browser sends consent submissions to Inth.
12
+
13
+ You can use a [self-hosted backend](https://c15t.com/docs/self-host/quickstart) with the same
14
+ configuration and your own endpoint. [Offline mode](./api-reference/data-fetching.md#offline-configuration)
15
+ uses bundled policy and browser storage without backend records. Not recommended
16
+ for production environments.
17
+
18
+ This setup needs a Next.js server. For `output: 'export'`, follow
19
+ [static export](./static-export.md). For a smaller setup with no
20
+ local API routes, use [client-side initialization](./client-side.md).
21
+ Same-origin [rewrites](./optimization.md) are optional.
22
+
23
+ Location-based policies need trusted location headers from your host. Without
24
+ them, c15t uses your unknown-location rule. Check the supported
25
+ [geography headers](./api-reference/data-fetching.md#geography-and-privacy-signals)
26
+ before deploying.
27
+
28
+ The setup below uses `getServerSideProps` for request-specific consent. Pages
29
+ without prefetch initialize in the browser through the same `ConsentRoot`.
30
+
31
+ ## Install c15t and configure your backend
32
+
33
+ [Create an Inth project](https://inth.com), configure its policy rules and allow
34
+ your app's origin. Copy its backend endpoint for the upstream configuration.
35
+
36
+ If you chose self-hosting, complete the
37
+ [backend quickstart](https://c15t.com/docs/self-host/quickstart) and use its public endpoint in
38
+ the steps below. Offline setups do not need an endpoint; use the
39
+ [offline example](./api-reference/data-fetching.md#offline-configuration).
40
+
41
+ | Package manager | Command |
42
+ | :-------------- | :----------------- |
43
+ | npm | `npm install c15t` |
44
+ | pnpm | `pnpm add c15t` |
45
+ | yarn | `yarn add c15t` |
46
+ | bun | `bun add c15t` |
47
+
48
+ | Package manager | Command |
49
+ | :-------------- | :-------------------------- |
50
+ | npm | `npm install @c15t/scripts` |
51
+ | pnpm | `pnpm add @c15t/scripts` |
52
+ | yarn | `yarn add @c15t/scripts` |
53
+ | bun | `bun add @c15t/scripts` |
54
+
55
+ Set `NEXT_PUBLIC_C15T_BACKEND_URL` to the absolute endpoint supplied by Inth or
56
+ your self-hosted backend, including any path prefix. This is a public endpoint,
57
+ not a secret. Configure the backend to allow your app's origin.
58
+
59
+ ## Share the consent URLs
60
+
61
+ Create this file at the project root. Set `manifestURL` explicitly to select
62
+ manifest resolution.
63
+
64
+ ```ts title="c15t.config.ts"
65
+ import { defineConsentConfig } from 'c15t/next';
66
+
67
+ const backendURL = process.env.NEXT_PUBLIC_C15T_BACKEND_URL;
68
+ if (!backendURL) throw new Error('Set NEXT_PUBLIC_C15T_BACKEND_URL');
69
+
70
+ export const consentConfig = defineConsentConfig({
71
+ backendURL,
72
+ manifestURL: '/api/c15t/manifest',
73
+ });
74
+ ```
75
+
76
+ ## Add the manifest API route
77
+
78
+ The Pages Router adapter reads `C15T_BACKEND_URL`, falling back to the
79
+ `NEXT_PUBLIC_C15T_BACKEND_URL` configured above. If you set both, use the same
80
+ absolute backend endpoint.
81
+
82
+ ```ts title="pages/api/c15t/manifest.ts"
83
+ import { createPagesApiHandlers } from 'c15t/next/pages';
84
+
85
+ export default createPagesApiHandlers().manifest;
86
+ ```
87
+
88
+ The manifest route caches public policy data. Server prefetch resolves it
89
+ using the visitor's request. Consent submissions go directly to `backendURL`.
90
+
91
+ The following imports assume `pages/` is at the project root. Adjust them if you
92
+ use `src/pages/`.
93
+
94
+ ## Register scripts in a client wrapper
95
+
96
+ The [runnable Next.js example](https://c15t.com/docs/examples) uses PostHog for measurement and
97
+ X Pixel for marketing. Set `NEXT_PUBLIC_POSTHOG_KEY` and
98
+ `NEXT_PUBLIC_X_PIXEL_ID` to your own project identifiers before building.
99
+ `NEXT_PUBLIC_POSTHOG_HOST` optionally selects your PostHog region's API host.
100
+ Omit a vendor's ID to leave that integration disabled, or replace its helper
101
+ with the [integration](../../integrations/overview.md) your application uses. Include the
102
+ measurement and marketing categories in your policy for these two vendors.
103
+
104
+ Create `lib/scripts.ts` with the example's script configuration:
105
+
106
+ ```ts title="lib/scripts.ts"
107
+ import { posthog } from '@c15t/scripts/posthog';
108
+ import { xPixel } from '@c15t/scripts/x-pixel';
109
+ import type { Script } from 'c15t';
110
+
111
+ export const posthogConfigured = Boolean(process.env.NEXT_PUBLIC_POSTHOG_KEY);
112
+ export const xPixelConfigured = Boolean(process.env.NEXT_PUBLIC_X_PIXEL_ID);
113
+
114
+ export const scripts: Script[] = [];
115
+
116
+ if (process.env.NEXT_PUBLIC_POSTHOG_KEY) {
117
+ scripts.push(
118
+ posthog({
119
+ apiHost: process.env.NEXT_PUBLIC_POSTHOG_HOST,
120
+ id: process.env.NEXT_PUBLIC_POSTHOG_KEY,
121
+ initOptions: { cookieless_mode: 'never' },
122
+ loadMode: 'after-consent',
123
+ })
124
+ );
125
+ }
126
+
127
+ if (process.env.NEXT_PUBLIC_X_PIXEL_ID) {
128
+ scripts.push(xPixel({ pixelId: process.env.NEXT_PUBLIC_X_PIXEL_ID }));
129
+ }
130
+ ```
131
+
132
+ PostHog waits for measurement consent here. `cookieless_mode: 'never'` disables
133
+ cookieless capture after rejection. X Pixel waits for marketing consent. Remove
134
+ any existing loader for these vendors, including `next/script` and tag-manager
135
+ entries, so each integration loads once.
136
+
137
+ Create this client wrapper. It keeps scripts and browser callbacks in the client
138
+ while the router supplies the visitor's resolved state through `state`:
139
+
140
+ ```tsx title="components/consent.tsx"
141
+ 'use client';
142
+
143
+ import type { ReactNode } from 'react';
144
+ import {
145
+ ConsentBanner,
146
+ ConsentDialog,
147
+ ConsentDialogLink,
148
+ ConsentRoot,
149
+ } from 'c15t/next';
150
+ import type { ConsentRootProps } from 'c15t/next';
151
+ import { consentConfig } from '../c15t.config';
152
+ import { scripts } from '../lib/scripts';
153
+
154
+ export function Consent({
155
+ children,
156
+ state,
157
+ }: {
158
+ children: ReactNode;
159
+ state: ConsentRootProps['state'];
160
+ }) {
161
+ return (
162
+ <ConsentRoot state={state} config={consentConfig} scripts={scripts}>
163
+ {children}
164
+ <ConsentBanner />
165
+ <ConsentDialog />
166
+ <footer>
167
+ <ConsentDialogLink>Privacy settings</ConsentDialogLink>
168
+ </footer>
169
+ </ConsentRoot>
170
+ );
171
+ }
172
+ ```
173
+
174
+ `ConsentRoot` already provides the consent runtime. Mount this wrapper once;
175
+ do not add a second provider. Keep your site's content and footer inside it.
176
+
177
+ ## Keep one root in the app
178
+
179
+ Add c15t to your global stylesheet. With Tailwind CSS 4, keep its import first:
180
+
181
+ ```css title="styles/globals.css"
182
+ @import 'tailwindcss';
183
+ @import 'c15t/next/styles.css';
184
+ ```
185
+
186
+ Without Tailwind, omit its import. For Tailwind CSS 3, use the
187
+ [separate stylesheet recipe](./styling/overview.md#stylesheet).
188
+ Keep any existing app styles and adjust the import below to their location.
189
+
190
+ ```tsx title="pages/_app.tsx"
191
+ import type { AppProps } from 'next/app';
192
+ import type { ConsentRootProps } from 'c15t/next';
193
+ import { Consent } from '../components/consent';
194
+ import '../styles/globals.css';
195
+
196
+ type ConsentPageProps = {
197
+ consentState?: ConsentRootProps['state'];
198
+ };
199
+
200
+ export default function App({ Component, pageProps }: AppProps<ConsentPageProps>) {
201
+ return (
202
+ <Consent state={pageProps.consentState ?? {}}>
203
+ <Component {...pageProps} />
204
+ </Consent>
205
+ );
206
+ }
207
+ ```
208
+
209
+ `consentState` is the visitor's resolved state; `consentConfig` contains the
210
+ shared URLs. Without page prefetch, the browser loads the manifest and resolves
211
+ policy locally. Without supplied location, geography is unknown. For browser
212
+ initialization with request geography, see the
213
+ [optional local init route](./api-reference/data-fetching.md#do-i-need-the-local-init-route).
214
+ Consent submissions go to `${backendURL}/subjects` on the configured backend.
215
+
216
+ ## Prefetch for a server-rendered page
217
+
218
+ Use `c15t/next/pages` with the `req` from `getServerSideProps`. The App Router
219
+ helper reads a different request context and must not be used here.
220
+
221
+ ```tsx title="pages/index.tsx"
222
+ import type { GetServerSideProps } from 'next';
223
+ import type { ConsentRootProps } from 'c15t/next';
224
+ import { resolveConsent } from 'c15t/next/pages';
225
+ import { consentConfig } from '../c15t.config';
226
+
227
+ type PageProps = { consentState: ConsentRootProps['state'] };
228
+
229
+ export const getServerSideProps: GetServerSideProps<PageProps> = async ({ req }) => {
230
+ const state = await resolveConsent({ config: consentConfig, req });
231
+ return {
232
+ props: {
233
+ consentState: JSON.parse(
234
+ JSON.stringify(state)
235
+ ) as PageProps['consentState'],
236
+ },
237
+ };
238
+ };
239
+
240
+ export default function Home() {
241
+ return <main>Your page</main>;
242
+ }
243
+ ```
244
+
245
+ The JSON round-trip removes `undefined` fields, such as an absent GPC signal,
246
+ because Next.js rejects them in `getServerSideProps` props.
247
+
248
+ Repeat prefetch on pages that need request-specific initial HTML. Do not use
249
+ `getStaticProps` to resolve visitor cookies or geography: it runs without the
250
+ visitor's request. Keep the shared URL configuration consistent across pages.
251
+
252
+ ## Verify entry and navigation
253
+
254
+ For an opt-in policy, reject and confirm neither configured vendor loads. Allow
255
+ measurement only: PostHog can load, while X Pixel stays blocked. Revoke
256
+ measurement from Privacy settings and check PostHog's capture is disabled.
257
+ See [script loading](./script-loader.md) for vendor-specific
258
+ loading and revocation behavior.
259
+
260
+ Load a server-rendered page directly, reject, and reload. Then navigate without
261
+ a full reload and reopen preferences. The mounted boundary should retain the
262
+ choice. Also test direct entry to a statically generated page; it uses browser
263
+ manifest resolution, so verify your unknown-location rule.
264
+
265
+ Confirm the server reads `/manifest` instead of the backend `/init` and choices
266
+ reach `${backendURL}/subjects`. See
267
+ [Optimization](./optimization.md) for caching, or compare
268
+ alternatives in [data fetching](./data-fetching.md). For a deployment with no Next.js server, use
269
+ [static export](./static-export.md) and remove local API routes.
270
+
271
+ ## Use regular backend initialization instead
272
+
273
+ For a complete browser-only setup with hosted records, follow
274
+ [client-side initialization](./client-side.md). It needs no
275
+ local route handlers or server prefetch.
276
+
277
+ For the smallest hosted configuration, keep only `backendURL` in
278
+ `defineConsentConfig`:
279
+
280
+ ```ts title="c15t.config.ts"
281
+ import { defineConsentConfig } from 'c15t/next';
282
+
283
+ const backendURL = process.env.NEXT_PUBLIC_C15T_BACKEND_URL;
284
+ if (!backendURL) throw new Error('Set NEXT_PUBLIC_C15T_BACKEND_URL');
285
+
286
+ export const consentConfig = defineConsentConfig({ backendURL });
287
+ ```
288
+
289
+ This is an alternative to the manifest configuration. Remove the unused local
290
+ manifest route. The existing prefetch and boundary now initialize
291
+ through `${backendURL}/init`; consent saves still use `${backendURL}/subjects`.
292
+ A backend-only config does not enable manifest mode automatically.
293
+
294
+ Compare the choices in [data fetching](./data-fetching.md), or
295
+ configure cache settings and optional rewrites in
296
+ [Optimization](./optimization.md).
@@ -1,145 +1,44 @@
1
1
  ---
2
2
  title: Quickstart
3
- description: Add consent management to your Next.js app in under 5 minutes.
4
- variants:
5
- - value: javascript
6
- href: /docs/frameworks/javascript/quickstart
7
- label: JavaScript
8
- - value: react
9
- href: /docs/frameworks/react/quickstart
10
- label: React
11
- - value: next
12
- href: /docs/frameworks/next/quickstart
13
- label: Next.js
3
+ description: Add c15t consent management to Next.js with Inth, with setup guides
4
+ for the App Router, the Pages Router and static export.
14
5
  group: frameworks
15
6
  ---
16
- ## Via CLI
17
7
 
18
- <PackageCommandTabs command="@c15t/cli" />
8
+ ## Choose your setup
19
9
 
20
- ## Manual Installation
10
+ We recommend [Inth](https://inth.com) for policy management and consent records.
11
+ For Next.js server deployments, the guides use cached manifests: your server
12
+ reuses public policy data and resolves consent for each visitor. Static exports
13
+ initialize through Inth in the browser.
21
14
 
22
- 1. **Install package**
15
+ | Your deployment | Start here |
16
+ | ------------------------------------- | ----------------------------------- |
17
+ | App Router with a Next.js server | [App Router](./app-router.md) |
18
+ | Pages Router with a Next.js server | [Pages Router](./pages-router.md) |
19
+ | Either router with `output: 'export'` | [Static export](./static-export.md) |
23
20
 
24
- 2. **Import styles** Import the prebuilt component stylesheet in your app-level CSS entrypoint. This is required for styled components to render correctly.
21
+ Each guide includes installation, backend prerequisites, consent-gated scripts
22
+ and a persistent preferences link. Start with the guide for your deployment; you do not need to read
23
+ the fetching reference first.
25
24
 
26
- ```css
27
- @import "@c15t/nextjs/styles.css";
28
- ```
25
+ [Self-hosting](https://c15t.com/docs/self-host/quickstart) uses the same setup with your own
26
+ backend. [Offline mode](./api-reference/data-fetching.md#offline-configuration)
27
+ resolves bundled policy and keeps choices in browser storage, with no backend
28
+ requests or records. Not recommended for production environments.
29
29
 
30
- 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.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.
30
+ ## Other setup choices
31
31
 
32
- > ℹ️ Info:
33
- > If you are using the headless API or fully custom styling, you can skip this import. Your root layout should continue importing ./globals.css as usual.
32
+ For a smaller hosted setup without server prefetch or local API routes, use
33
+ [client-side initialization](./client-side.md). Consent resolves
34
+ in the browser, so the initial HTML has no resolved consent prompt.
34
35
 
35
- 3. **Create ConsentManager components** Create a provider component with the consent UI and a wrapper that re-exports it. This initializes the consent store and makes consent state available to all child components.
36
+ [Data fetching](./data-fetching.md) compares manifests and regular
37
+ backend initialization. [Server rendering](./server-side.md)
38
+ explains when to await consent or stream the page while it resolves. Same-origin
39
+ [rewrites](./optimization.md) are optional optimizations.
36
40
 
37
- ```tsx
38
- 'use client';
39
-
40
- import { type ReactNode } from 'react';
41
- import {
42
- ConsentManagerProvider,
43
- ConsentBanner,
44
- ConsentDialog,
45
- } from '@c15t/nextjs';
46
-
47
- export default function ConsentManagerClient({ children }: { children: ReactNode }) {
48
- return (
49
- <ConsentManagerProvider
50
- options={{
51
- mode: 'hosted',
52
- backendURL: 'https://your-instance.c15t.dev',
53
- consentCategories: ['necessary', 'measurement', 'marketing'],
54
- // Shows banner during development. Remove for production.
55
- overrides: { country: 'DE' },
56
- }}
57
- >
58
- <ConsentBanner />
59
- <ConsentDialog />
60
- {children}
61
- </ConsentManagerProvider>
62
- );
63
- }
64
- ```
65
-
66
- ```tsx
67
- import type { ReactNode } from 'react';
68
- import ConsentManagerProvider from './provider';
69
-
70
- export function ConsentManager({ children }: { children: ReactNode }) {
71
- return <ConsentManagerProvider>{children}</ConsentManagerProvider>;
72
- }
73
- ```
74
-
75
- > ℹ️ Info:
76
- > Hosted mode is the recommended production setup because the backend resolves jurisdiction and policy, keeps durable consent records, and lets c15t recover from temporary network failures by re-syncing later.
77
- >
78
- > ⚠️ Warning:
79
- > Don't have a backend yet? You can use mode: 'offline' for local-only consent storage, but it gives up backend audit history, server-side consent awareness, and automatic jurisdiction detection. Review the browser-only storage consequences before choosing it for production.
80
-
81
- 4. **Mount ConsentManager at the app root** Wrap your app tree with `ConsentManager` so all routes/components can access consent state.
82
-
83
- ```tsx
84
- import { ConsentManager } from '@/components/consent-manager';
85
-
86
- export default function RootLayout({ children }: { children: React.ReactNode }) {
87
- return (
88
- <html lang="en">
89
- <body>
90
- <ConsentManager>{children}</ConsentManager>
91
- </body>
92
- </html>
93
- );
94
- }
95
- ```
96
-
97
- 5. **Verify it works** Start your development server and confirm:
98
-
99
- 1. A **consent banner** appears at the bottom of the page
100
- 2. Clicking **"Customize"** opens a dialog with toggles for each consent category
101
- 3. After accepting or rejecting, the banner dismisses and your choice persists across page reloads
102
-
103
- > ℹ️ **Info:**
104
- > Want better performance and static-route support? See Optimization for rewrites, prefetching, and network tuning. If you want server-side data prefetching, see Server-Side Data Fetching.
105
-
106
- ## Optional: Add DevTools
107
-
108
- Install DevTools only if you want a runtime inspector while building and debugging:
109
-
110
- <PackageCommandTabs mode="install" command="@c15t/dev-tools" />
111
-
112
- Then add it inside your existing provider:
113
-
114
- ```tsx title="components/consent-manager/provider.tsx"
115
- import { DevTools } from '@c15t/dev-tools/react';
116
-
117
- // ...
118
-
119
- <ConsentManagerProvider options={...}>
120
- <ConsentBanner />
121
- <ConsentDialog />
122
- {process.env.NODE_ENV !== 'production' && <DevTools />}
123
- {children}
124
- </ConsentManagerProvider>
125
- ```
126
-
127
- > ℹ️ **Info:**
128
- > Want to understand what's happening under the hood? See Initialization Flow for the lifecycle and Cookie Management for script/cookie behavior and revocation handling.
129
-
130
- ## Optional: AI Agents
131
-
132
- Install c15t agent skills to let AI agents help with styling, i18n, scripts & other configuration.
133
-
134
- <PackageCommandTabs command="@c15t/cli skills" />
135
-
136
- See [AI Agents](/docs/ai-agents) for bundled package docs and agent skills.
137
-
138
- ## Next steps
139
-
140
- * [Optimization](/docs/frameworks/next/optimization)
141
- * [Script Loader](/docs/frameworks/next/script-loader)
142
- * [Styling](/docs/frameworks/next/styling/overview)
143
- * [Consent Categories](/docs/frameworks/next/concepts/consent-categories)
144
- * [Components](/docs/frameworks/next/components/consent-banner)
145
- * [AI Agents](/docs/ai-agents)
41
+ Try the [runnable Next.js example](https://c15t.com/docs/examples) with both routers, a gated
42
+ YouTube video, PostHog, X Pixel and custom banner designs. The router guides use
43
+ the same script configuration. After setup, [verify requests and persistence](../../guides/verify-consent.md);
44
+ a visible banner alone does not establish that analytics wait for consent.