@c15t/nextjs 2.2.1 → 3.0.0-alpha.1

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 (221) hide show
  1. package/AGENTS.md +103 -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 +27 -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 +67 -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 +92 -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 +103 -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 +68 -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 +140 -465
  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 +174 -248
  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/clear-on-revocation.md +167 -0
  82. package/docs/integrations/clearbit.md +247 -86
  83. package/docs/integrations/cloudflare-web-analytics.md +250 -84
  84. package/docs/integrations/crisp.md +251 -97
  85. package/docs/integrations/databuddy.md +259 -153
  86. package/docs/integrations/fathom-analytics.md +239 -96
  87. package/docs/integrations/google-maps.md +328 -207
  88. package/docs/integrations/google-tag-manager.md +248 -96
  89. package/docs/integrations/google-tag.md +261 -90
  90. package/docs/integrations/heap.md +222 -149
  91. package/docs/integrations/hightouch.md +225 -131
  92. package/docs/integrations/hotjar.md +239 -90
  93. package/docs/integrations/intercom.md +239 -98
  94. package/docs/integrations/linkedin-insights.md +243 -113
  95. package/docs/integrations/logrocket.md +241 -123
  96. package/docs/integrations/matomo-analytics.md +256 -111
  97. package/docs/integrations/meta-pixel.md +197 -324
  98. package/docs/integrations/microsoft-clarity.md +233 -114
  99. package/docs/integrations/microsoft-uet.md +245 -110
  100. package/docs/integrations/mixpanel-analytics.md +252 -87
  101. package/docs/integrations/openai-pixel.md +441 -0
  102. package/docs/integrations/overview.md +95 -133
  103. package/docs/integrations/pirsch.md +249 -96
  104. package/docs/integrations/plausible-analytics.md +241 -100
  105. package/docs/integrations/posthog.md +353 -214
  106. package/docs/integrations/promptwatch.md +251 -81
  107. package/docs/integrations/reddit-pixel.md +226 -173
  108. package/docs/integrations/rudderstack.md +244 -187
  109. package/docs/integrations/rybbit-analytics.md +244 -91
  110. package/docs/integrations/segment.md +238 -92
  111. package/docs/integrations/snapchat-pixel.md +240 -110
  112. package/docs/integrations/tiktok-pixel.md +249 -81
  113. package/docs/integrations/umami-analytics.md +242 -95
  114. package/docs/integrations/vercel-analytics.md +242 -90
  115. package/docs/integrations/x-pixel.md +238 -104
  116. package/docs/integrations/youtube.md +354 -142
  117. package/docs/upgrade-v3.md +334 -0
  118. package/iab/styles.css +1 -1
  119. package/iab/styles.tw3.css +1 -1
  120. package/package.json +106 -65
  121. package/readme.json +3 -3
  122. package/src/iab/styles.css +1 -1
  123. package/src/iab/styles.tw3.css +1 -1
  124. package/src/styles.css +1 -1
  125. package/src/styles.tw3.css +1 -1
  126. package/styles.css +1 -1
  127. package/styles.tw3.css +1 -1
  128. package/client/components/consent-dialog-link.js +0 -3
  129. package/client/components/integrations.js +0 -3
  130. package/dist/components/integrations/index.cjs +0 -1
  131. package/dist/components/integrations/index.js +0 -1
  132. package/dist/headless.cjs +0 -1
  133. package/dist/index.cjs +0 -1
  134. package/dist/libs/browser-initial-data.cjs +0 -1
  135. package/dist/libs/browser-initial-data.js +0 -1
  136. package/dist/libs/initial-data.cjs +0 -1
  137. package/dist/libs/initial-data.js +0 -1
  138. package/dist/types.cjs +0 -1
  139. package/dist/version.cjs +0 -1
  140. package/dist-types/components/integrations/index.d.ts +0 -1
  141. package/dist-types/libs/browser-initial-data.d.ts +0 -9
  142. package/dist-types/libs/initial-data.d.ts +0 -33
  143. package/docs/frameworks/next/building-headless-components.md +0 -379
  144. package/docs/frameworks/next/callbacks.md +0 -186
  145. package/docs/frameworks/next/concepts/client-modes.md +0 -177
  146. package/docs/frameworks/next/concepts/consent-models.md +0 -117
  147. package/docs/frameworks/next/concepts/cookie-management.md +0 -122
  148. package/docs/frameworks/next/concepts/glossary.md +0 -24
  149. package/docs/frameworks/next/concepts/initialization-flow.md +0 -149
  150. package/docs/frameworks/next/concepts/policy-packs.md +0 -230
  151. package/docs/frameworks/next/hooks/use-color-scheme.md +0 -41
  152. package/docs/frameworks/next/hooks/use-consent-manager/checking-consent.md +0 -96
  153. package/docs/frameworks/next/hooks/use-consent-manager/location-info.md +0 -97
  154. package/docs/frameworks/next/hooks/use-consent-manager/setting-consent.md +0 -94
  155. package/docs/frameworks/next/hooks/use-draggable.md +0 -59
  156. package/docs/frameworks/next/hooks/use-focus-trap.md +0 -42
  157. package/docs/frameworks/next/hooks/use-reduced-motion.md +0 -37
  158. package/docs/frameworks/next/hooks/use-ssr-status.md +0 -32
  159. package/docs/frameworks/next/hooks/use-text-direction.md +0 -50
  160. package/docs/frameworks/next/hooks/use-translations.md +0 -55
  161. package/docs/frameworks/next/iab/consent-banner.md +0 -91
  162. package/docs/frameworks/next/iab/consent-dialog.md +0 -129
  163. package/docs/frameworks/next/iab/use-gvl-data.md +0 -21
  164. package/docs/frameworks/next/iframe-blocking.md +0 -106
  165. package/docs/frameworks/next/internationalization.md +0 -207
  166. package/docs/frameworks/next/network-blocker.md +0 -140
  167. package/docs/frameworks/next/policy-packs.md +0 -248
  168. package/docs/frameworks/next/styling/classnames.md +0 -94
  169. package/docs/frameworks/next/styling/color-scheme.md +0 -84
  170. package/docs/frameworks/next/styling/css-variables.md +0 -53
  171. package/docs/frameworks/next/styling/slots.md +0 -94
  172. package/docs/frameworks/next/styling/tailwind.md +0 -137
  173. package/docs/frameworks/next/styling/tokens.md +0 -156
  174. package/docs/shared/concepts/client-modes.md +0 -103
  175. package/docs/shared/concepts/consent-categories.md +0 -41
  176. package/docs/shared/concepts/consent-models.md +0 -72
  177. package/docs/shared/concepts/cookie-management.md +0 -88
  178. package/docs/shared/concepts/glossary.md +0 -24
  179. package/docs/shared/concepts/initialization-flow.md +0 -105
  180. package/docs/shared/concepts/policy-packs.md +0 -225
  181. package/docs/shared/react/components/consent-banner.md +0 -242
  182. package/docs/shared/react/components/consent-dialog-link.md +0 -45
  183. package/docs/shared/react/components/consent-dialog-trigger.md +0 -185
  184. package/docs/shared/react/components/consent-dialog.md +0 -119
  185. package/docs/shared/react/components/consent-manager-provider.md +0 -225
  186. package/docs/shared/react/components/consent-widget.md +0 -121
  187. package/docs/shared/react/components/dev-tools.md +0 -81
  188. package/docs/shared/react/components/frame.md +0 -52
  189. package/docs/shared/react/guides/building-headless-components.md +0 -110
  190. package/docs/shared/react/guides/callbacks.md +0 -89
  191. package/docs/shared/react/guides/headless.md +0 -31
  192. package/docs/shared/react/guides/iframe-blocking.md +0 -65
  193. package/docs/shared/react/guides/internationalization.md +0 -123
  194. package/docs/shared/react/guides/network-blocker.md +0 -72
  195. package/docs/shared/react/guides/optimization.md +0 -44
  196. package/docs/shared/react/guides/policy-packs.md +0 -173
  197. package/docs/shared/react/guides/script-loader.md +0 -311
  198. package/docs/shared/react/hooks/use-color-scheme.md +0 -31
  199. package/docs/shared/react/hooks/use-consent-manager/checking-consent.md +0 -95
  200. package/docs/shared/react/hooks/use-consent-manager/location-info.md +0 -96
  201. package/docs/shared/react/hooks/use-consent-manager/overview.md +0 -74
  202. package/docs/shared/react/hooks/use-consent-manager/setting-consent.md +0 -93
  203. package/docs/shared/react/hooks/use-draggable.md +0 -30
  204. package/docs/shared/react/hooks/use-focus-trap.md +0 -20
  205. package/docs/shared/react/hooks/use-reduced-motion.md +0 -33
  206. package/docs/shared/react/hooks/use-ssr-status.md +0 -16
  207. package/docs/shared/react/hooks/use-text-direction.md +0 -38
  208. package/docs/shared/react/hooks/use-translations.md +0 -15
  209. package/docs/shared/react/iab/consent-banner.md +0 -60
  210. package/docs/shared/react/iab/consent-dialog.md +0 -76
  211. package/docs/shared/react/iab/overview.md +0 -80
  212. package/docs/shared/react/iab/use-gvl-data.md +0 -21
  213. package/docs/shared/react/styling/classnames.md +0 -93
  214. package/docs/shared/react/styling/color-scheme.md +0 -35
  215. package/docs/shared/react/styling/css-variables.md +0 -53
  216. package/docs/shared/react/styling/overview.md +0 -261
  217. package/docs/shared/react/styling/slots.md +0 -93
  218. package/docs/shared/react/styling/stylesheet-entrypoint.md +0 -8
  219. package/docs/shared/react/styling/tailwind.md +0 -88
  220. package/docs/shared/react/styling/tokens.md +0 -155
  221. package/docs/shared/troubleshooting.md +0 -82
@@ -0,0 +1,88 @@
1
+ import type { ConsentManifest, ConsentManifestGVLReference, GlobalVendorList } from '@c15t/schema/types';
2
+ import type { ConsentConfig } from './config';
3
+ type NextFetchInit = RequestInit & {
4
+ next?: {
5
+ revalidate?: number | false;
6
+ tags?: string[];
7
+ };
8
+ };
9
+ export interface NextConsentManifestHandlersOptions {
10
+ /**
11
+ * Backend base URL that serves `/manifest`.
12
+ * Defaults to `C15T_BACKEND_URL` or `NEXT_PUBLIC_C15T_BACKEND_URL`.
13
+ */
14
+ backendURL?: string;
15
+ /**
16
+ * Full manifest URL. Overrides `backendURL + "/manifest"`.
17
+ * Defaults to `C15T_MANIFEST_URL`.
18
+ */
19
+ manifestURL?: string;
20
+ /**
21
+ * Next.js Data Cache lifetime for the manifest fetch.
22
+ * Defaults to the backend manifest route's default `s-maxage` of 300s.
23
+ */
24
+ manifestRevalidateSeconds?: number | false;
25
+ fetch?: typeof globalThis.fetch;
26
+ /**
27
+ * Receives the promise of a background manifest revalidation started by
28
+ * a request, so the host can keep it alive past the response on runtimes
29
+ * that stop detached work once a response is sent. Called inside the
30
+ * handler, so `after` from `next/server` (Next 15.1 and later; 15.0
31
+ * exposes it as `unstable_after`) can be used directly. The promise
32
+ * never rejects. Not called when the manifest is fresh or the request
33
+ * itself waits on the upstream.
34
+ *
35
+ * @example
36
+ * ```ts
37
+ * import { after } from 'next/server';
38
+ *
39
+ * createNextConsentRouteHandlers({
40
+ * ...consentConfig,
41
+ * onBackgroundRevalidate: (refresh) => after(() => refresh),
42
+ * });
43
+ * ```
44
+ */
45
+ onBackgroundRevalidate?: (revalidation: Promise<void>) => void;
46
+ fetchGvl?: (input: {
47
+ reference: ConsentManifestGVLReference;
48
+ language: string;
49
+ fetch: typeof globalThis.fetch;
50
+ }) => Promise<GlobalVendorList | null>;
51
+ }
52
+ export interface ManifestFetchResult {
53
+ manifest: ConsentManifest;
54
+ cacheControl: string;
55
+ etag?: string;
56
+ revalidate: number | false;
57
+ status: number;
58
+ }
59
+ export declare const getSMaxAge: (cacheControl: string | null) => number | undefined;
60
+ export declare const createManifestFetchInit: (options?: NextConsentManifestHandlersOptions) => NextFetchInit;
61
+ export declare const fetchCachedManifest: (request: Request, options?: NextConsentManifestHandlersOptions, language?: string | null) => Promise<ManifestFetchResult & {
62
+ age: number;
63
+ }>;
64
+ /**
65
+ * Build the App Router route handlers for the consent routes.
66
+ *
67
+ * @param options - Handler options, or a `defineConsentConfig` result. From a
68
+ * config only `backendURL` is used: its `manifestURL` and `initURL` are the
69
+ * routes these handlers serve.
70
+ * @returns `GET` for the init route and `manifestGET` for the manifest route.
71
+ * @example
72
+ * ```ts
73
+ * // app/api/consent/manifest/route.ts
74
+ * import { createNextConsentRouteHandlers } from '@c15t/nextjs/api';
75
+ * import { consentConfig } from '@/consent.config';
76
+ *
77
+ * export const { manifestGET: GET } =
78
+ * createNextConsentRouteHandlers(consentConfig);
79
+ * ```
80
+ */
81
+ export declare const createNextConsentRouteHandlers: (optionsOrConfig?: NextConsentManifestHandlersOptions | ConsentConfig) => {
82
+ GET(request: Request): Promise<Response>;
83
+ manifestGET(request: Request): Promise<Response>;
84
+ };
85
+ export type { ConsentConfig } from './config';
86
+ export { defineConsentConfig } from './config';
87
+ export declare const GET: (request: Request) => Promise<Response>;
88
+ export declare const manifestGET: (request: Request) => Promise<Response>;
@@ -0,0 +1,110 @@
1
+ /**
2
+ * `defineConsentConfig` — the URLs a Next.js consent setup needs, declared
3
+ * once and shared by the route handlers, `resolveConsent`, and the client
4
+ * `ConsentRoot`.
5
+ *
6
+ * Plain data with no `next` imports, so the same module is safe to import
7
+ * from a route file, a Server Component, and a `'use client'` file.
8
+ */
9
+ /**
10
+ * URLs shared by every side of a Next.js consent setup.
11
+ */
12
+ export interface ConsentConfig {
13
+ /**
14
+ * Backend base URL; `/subjects` writes and, without a manifest, `/init`
15
+ * reads go here.
16
+ */
17
+ backendURL: string;
18
+ /**
19
+ * Same-origin route that serves the cached manifest (from
20
+ * `createNextConsentRouteHandlers`). Enables manifest mode.
21
+ */
22
+ manifestURL?: string;
23
+ /**
24
+ * Same-origin route that resolves init from the cached manifest with the
25
+ * request's geo (the handlers' `GET`). Enables geo in the browser without
26
+ * a backend `/init` call.
27
+ */
28
+ initURL?: string;
29
+ }
30
+ /**
31
+ * Declare the consent URLs once and hand the result to every side of the
32
+ * setup: `createNextConsentRouteHandlers` (route file), `resolveConsent`
33
+ * (Server Component or `getServerSideProps`), and `ConsentRoot` (client).
34
+ * Each reads the fields it needs, so the URLs are never repeated.
35
+ *
36
+ * The returned object is frozen plain data: no `next` imports, safe to
37
+ * import from a `'use client'` file, and serializable as a Server Component
38
+ * prop.
39
+ *
40
+ * @param config - Backend base URL plus the optional same-origin routes.
41
+ * @returns The validated, frozen config.
42
+ * @throws {TypeError} When `backendURL` is missing, or any URL is neither an
43
+ * absolute `http(s)` URL nor a `/`-relative path.
44
+ * @example
45
+ * Manifest mode with browser geo, in three files.
46
+ *
47
+ * ```ts
48
+ * // consent.config.ts
49
+ * import { defineConsentConfig } from '@c15t/nextjs';
50
+ *
51
+ * export const consentConfig = defineConsentConfig({
52
+ * backendURL: 'https://consent.example.com',
53
+ * // Same-origin routes served by the handlers below.
54
+ * manifestURL: '/api/consent/manifest',
55
+ * initURL: '/api/consent/init',
56
+ * });
57
+ * ```
58
+ *
59
+ * ```ts
60
+ * // app/api/consent/manifest/route.ts
61
+ * import { createNextConsentRouteHandlers } from '@c15t/nextjs/api';
62
+ * import { consentConfig } from '@/consent.config';
63
+ *
64
+ * export const { manifestGET: GET } =
65
+ * createNextConsentRouteHandlers(consentConfig);
66
+ * ```
67
+ *
68
+ * ```ts
69
+ * // app/api/consent/init/route.ts
70
+ * import { createNextConsentRouteHandlers } from '@c15t/nextjs/api';
71
+ * import { consentConfig } from '@/consent.config';
72
+ *
73
+ * export const { GET } = createNextConsentRouteHandlers(consentConfig);
74
+ * ```
75
+ *
76
+ * ```tsx
77
+ * // app/layout.tsx
78
+ * import { ConsentRoot } from '@c15t/nextjs';
79
+ * import { resolveConsent } from '@c15t/nextjs/server';
80
+ * import { consentConfig } from '@/consent.config';
81
+ *
82
+ * export default async function RootLayout({ children }) {
83
+ * const state = await resolveConsent({ config: consentConfig });
84
+ * return (
85
+ * <html>
86
+ * <body>
87
+ * <ConsentRoot state={state} config={consentConfig}>
88
+ * {children}
89
+ * </ConsentRoot>
90
+ * </body>
91
+ * </html>
92
+ * );
93
+ * }
94
+ * ```
95
+ *
96
+ * With `initURL` set, the browser fetches init from the same-origin
97
+ * `GET` handler, which resolves the cached manifest with the request's
98
+ * geo headers, so the visitor's country is known without a backend
99
+ * `/init` call. Consent saves still post to `${backendURL}/subjects`.
100
+ * Drop `initURL` to resolve init in the browser from `manifestURL`
101
+ * (no geo), or drop both for hosted mode against `${backendURL}/init`.
102
+ */
103
+ export declare const defineConsentConfig: (config: ConsentConfig) => ConsentConfig;
104
+ /**
105
+ * Whether a value came from {@link defineConsentConfig}. The brand is an
106
+ * enumerable symbol, so it survives object spread.
107
+ *
108
+ * @internal
109
+ */
110
+ export declare const isConsentConfig: (value: unknown) => value is ConsentConfig;
@@ -0,0 +1 @@
1
+ export * from '@c15t/react/devtools';
@@ -0,0 +1,4 @@
1
+ import type { ConsentRequestHeaderInputs, ResolveInitFromManifestInputs } from '@c15t/schema/types';
2
+ /** Normalized request values used to resolve consent policy. */
3
+ export type ConsentRequestInputs = ConsentRequestHeaderInputs & ResolveInitFromManifestInputs;
4
+ export { CONSENT_REQUEST_HEADER_NAMES, COUNTRY_HEADERS, consentInputsToOverrides, extractConsentRequestInputs, parseGlobalPrivacyControl, REGION_HEADERS, } from '@c15t/schema/types';
@@ -1,14 +1,32 @@
1
1
  /**
2
- * Main entry point for the C15T Next.js integration package.
3
- * Re-exports all necessary components, hooks, and utilities from the React package
4
- * and middleware for seamless integration with Next.js applications.
2
+ * `@c15t/nextjs` Next.js App Router adapter.
5
3
  *
6
- * @packageDocumentation
7
- * @see {@link @c15t/react} for React components and hooks
8
- * @see {@link ./middleware} for Next.js middleware integration
4
+ * Pattern:
5
+ * // app/layout.tsx (Server Component)
6
+ * import { resolveConsent } from '@c15t/nextjs/server';
7
+ * import { ConsentRoot } from '@c15t/nextjs';
8
+ *
9
+ * export default async function RootLayout({ children }) {
10
+ * const state = await resolveConsent();
11
+ * return (
12
+ * <html>
13
+ * <body>
14
+ * <ConsentRoot state={state}>{children}</ConsentRoot>
15
+ * </body>
16
+ * </html>
17
+ * );
18
+ * }
19
+ *
20
+ * // any client component
21
+ * import { useConsent } from '@c15t/react';
22
+ * const allowed = useConsent('marketing');
23
+ *
24
+ * Server helpers return serializable data and avoid module-level runtime
25
+ * caches, keeping requests isolated under Fluid Compute.
9
26
  */
10
27
  export * from '@c15t/react';
11
- export { buildPrefetchScript, type PrefetchOptions } from 'c15t';
12
- export { C15tPrefetch } from './libs/browser-initial-data';
13
- export { fetchInitialData } from './libs/initial-data';
14
- export type { C15tPrefetchProps, ConsentManagerProps, FetchInitialDataOptions, InitialDataPromise, } from './types';
28
+ export type { ConsentRootProps } from './root';
29
+ export { ConsentRoot } from './root';
30
+ export type { ConsentState } from './types';
31
+ export type { ConsentConfig } from './config';
32
+ export { defineConsentConfig } from './config';
@@ -0,0 +1,15 @@
1
+ /**
2
+ * `@c15t/nextjs/middleware` keeps the Next 15 name for the proxy helper.
3
+ *
4
+ * Next 16 renamed `middleware.ts` to `proxy.ts`; the implementation lives in
5
+ * `@c15t/nextjs/proxy` and this entry re-exports it under the old name.
6
+ */
7
+ import { c15tProxy } from './proxy';
8
+ export type { C15tProxyOptions as C15tMiddlewareOptions } from './proxy';
9
+ /**
10
+ * Alias of `c15tProxy` from `@c15t/nextjs/proxy` for `middleware.ts` files.
11
+ *
12
+ * Both names stay supported. Prefer `c15tProxy` in new code, and switch to it
13
+ * when you rename `middleware.ts` to `proxy.ts` on Next 16.
14
+ */
15
+ export declare const c15tMiddleware: typeof c15tProxy;
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Bridges Node's `http` request and response objects to the Web `Request`,
3
+ * `Response`, and `Headers` types the server helpers and route handlers
4
+ * speak. Typed structurally so the public `@c15t/nextjs/pages` surface does
5
+ * not depend on `@types/node`.
6
+ */
7
+ /**
8
+ * Node-style incoming headers: lowercase names, arrays for repeated headers.
9
+ * `IncomingHttpHeaders` from `node:http` satisfies this shape.
10
+ */
11
+ export type NodeIncomingHeaders = Record<string, string | string[] | undefined>;
12
+ /**
13
+ * The part of a Node `IncomingMessage` the server helpers read.
14
+ */
15
+ export interface NodeRequestLike {
16
+ headers: NodeIncomingHeaders;
17
+ }
18
+ /**
19
+ * The part of a Node `IncomingMessage` the API bridge reads. `NextApiRequest`
20
+ * and the `req` of `getServerSideProps` both satisfy it.
21
+ */
22
+ export interface NodeApiRequestLike extends NodeRequestLike {
23
+ /**
24
+ * Body already parsed by Next's API route `bodyParser`. Left undefined when
25
+ * the route disables the parser, in which case the raw stream is read.
26
+ */
27
+ body?: unknown;
28
+ method?: string;
29
+ url?: string;
30
+ [Symbol.asyncIterator]?: () => AsyncIterator<Uint8Array | string>;
31
+ }
32
+ /**
33
+ * The part of a Node `ServerResponse` the API bridge writes to.
34
+ * `NextApiResponse` satisfies it.
35
+ */
36
+ export interface NodeApiResponseLike {
37
+ statusCode: number;
38
+ setHeader: (name: string, value: string | string[]) => unknown;
39
+ write: (chunk: Uint8Array) => unknown;
40
+ end: (chunk?: Uint8Array) => unknown;
41
+ }
42
+ /**
43
+ * Converts Node-style incoming headers to a Web `Headers` instance.
44
+ * Repeated headers are joined with `, `; undefined entries are skipped.
45
+ */
46
+ export declare const toWebHeaders: (headers: NodeIncomingHeaders) => Headers;
47
+ /**
48
+ * Converts a Node `IncomingMessage` into a Web `Request`. The URL is rebuilt
49
+ * from `x-forwarded-proto`, `x-forwarded-host`/`host`, and `req.url`, the
50
+ * same inputs the route handlers use to resolve a relative backend URL.
51
+ */
52
+ export declare const toWebRequest: (req: NodeApiRequestLike) => Promise<Request>;
53
+ /**
54
+ * Writes a Web `Response` to a Node `ServerResponse`: status, headers
55
+ * (`set-cookie` as separate values), then the body streamed chunk by chunk.
56
+ */
57
+ export declare const writeWebResponse: (response: Response, res: NodeApiResponseLike) => Promise<void>;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * `@c15t/nextjs/pages` — Pages Router entry.
3
+ *
4
+ * `@c15t/nextjs/server` reads the request through `next/headers`, which only
5
+ * exists in the App Router, and `@c15t/nextjs/api` ships App Router route
6
+ * handlers (Web `Request` in, `Response` out). These wrappers take the Node
7
+ * `req`/`res` that `getServerSideProps` and API routes receive instead.
8
+ *
9
+ * @example
10
+ * ```ts
11
+ * // pages/index.tsx
12
+ * import { resolveConsent } from '@c15t/nextjs/pages';
13
+ *
14
+ * export const getServerSideProps = async ({ req }) => ({
15
+ * props: { state: await resolveConsent({ backendURL: '/api/c15t', req }) },
16
+ * });
17
+ * ```
18
+ */
19
+ import type { NextConsentManifestHandlersOptions } from './api';
20
+ import type { ConsentConfig } from './config';
21
+ import type { NodeApiRequestLike, NodeApiResponseLike, NodeRequestLike } from './node-bridge';
22
+ import type { ConsentState, KernelConfig, NextRequestContext, ResolveConsentOptions } from './server';
23
+ export type { NodeApiRequestLike, NodeApiResponseLike, NodeIncomingHeaders, NodeRequestLike, } from './node-bridge';
24
+ export type { ConsentConfig, ConsentState, KernelConfig, NextConsentManifestHandlersOptions, NextRequestContext, };
25
+ export { defineConsentConfig } from './config';
26
+ /**
27
+ * `resolveConsent` options with the Node request in place of the `request`
28
+ * adapter, which this entry derives from `req`.
29
+ */
30
+ export type PagesResolveConsentOptions = Omit<ResolveConsentOptions, 'request'> & {
31
+ /**
32
+ * The `req` from `getServerSideProps` or an API route.
33
+ */
34
+ req: NodeRequestLike;
35
+ };
36
+ /**
37
+ * Builds the `request` adapter the server helpers expect from a Node
38
+ * request. Headers convert to Web `Headers`; cookies come from the `cookie`
39
+ * header.
40
+ *
41
+ * @param req - `req` from `getServerSideProps` or an API route
42
+ * @returns A `NextRequestContext` for `@c15t/nextjs/server`
43
+ */
44
+ export declare const createPagesRequestContext: (req: NodeRequestLike) => NextRequestContext;
45
+ /**
46
+ * Resolve the visitor's consent state in `getServerSideProps`. Same
47
+ * behaviour as `resolveConsent` from `@c15t/nextjs/server`, reading cookies
48
+ * and geo headers from `req` instead of `next/headers`: without a backend
49
+ * URL it returns the request-only state, with one it also folds in the
50
+ * backend or manifest init. The result is plain JSON, so return it as a
51
+ * prop and hand it to `ConsentRoot`.
52
+ *
53
+ * @param options - Backend URL or a `defineConsentConfig` result, the Node
54
+ * `req`, and the server helper options
55
+ * @returns The visitor's JSON-serializable `ConsentState`
56
+ * @example
57
+ * ```ts
58
+ * export const getServerSideProps = async ({ req }) => ({
59
+ * props: { state: await resolveConsent({ config: consentConfig, req }) },
60
+ * });
61
+ * ```
62
+ */
63
+ export declare const resolveConsent: (options: PagesResolveConsentOptions) => Promise<ConsentState>;
64
+ /**
65
+ * A Pages Router API route handler: Node `req` in, Node `res` written.
66
+ */
67
+ export type PagesApiHandler = (req: NodeApiRequestLike, res: NodeApiResponseLike) => Promise<void>;
68
+ /**
69
+ * Pages Router API route handlers for the consent routes. Wraps
70
+ * `createNextConsentRouteHandlers` from `@c15t/nextjs/api` so each handler
71
+ * takes the Node `req`/`res` of a `pages/api` route.
72
+ *
73
+ * @param options - Same options as `createNextConsentRouteHandlers`, or a
74
+ * `defineConsentConfig` result
75
+ * @returns `init` for `GET /init` and `manifest` for `GET /manifest`
76
+ *
77
+ * @example
78
+ * ```ts
79
+ * // pages/api/consent/manifest.ts
80
+ * import { createPagesApiHandlers } from '@c15t/nextjs/pages';
81
+ *
82
+ * export default createPagesApiHandlers({ backendURL: '/api/c15t' }).manifest;
83
+ * ```
84
+ */
85
+ export declare const createPagesApiHandlers: (options?: NextConsentManifestHandlersOptions | ConsentConfig) => {
86
+ init: PagesApiHandler;
87
+ manifest: PagesApiHandler;
88
+ };
@@ -0,0 +1,34 @@
1
+ import { NextResponse } from 'next/server.js';
2
+ import type { NextRequest } from 'next/server.js';
3
+ export interface C15tProxyOptions {
4
+ /**
5
+ * Also persist normalized geo into cookies for runtimes that do not keep
6
+ * middleware request headers visible to RSC.
7
+ */
8
+ cookie?: boolean | {
9
+ countryName?: string;
10
+ regionName?: string;
11
+ };
12
+ }
13
+ /**
14
+ * Creates a `NextResponse.next()` that forwards normalized consent headers.
15
+ *
16
+ * Use from `proxy.ts` (Next 16) or `middleware.ts` (Next 15) when the
17
+ * deployment platform exposes geo to the proxy but strips it before Server
18
+ * Components or Route Handlers. `@c15t/nextjs/middleware` exports the same
19
+ * function as `c15tMiddleware`.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * // proxy.ts
24
+ * import { c15tProxy } from '@c15t/nextjs/proxy';
25
+ * import type { NextRequest } from 'next/server';
26
+ *
27
+ * export const proxy = (request: NextRequest) => c15tProxy(request);
28
+ * ```
29
+ *
30
+ * @param request - The incoming Next.js request.
31
+ * @param options - Header and cookie forwarding options.
32
+ * @returns A response that forwards normalized consent headers.
33
+ */
34
+ export declare const c15tProxy: (request: NextRequest, options?: C15tProxyOptions) => NextResponse;
@@ -0,0 +1,92 @@
1
+ import type { Script } from '@c15t/core/modules/script-loader';
2
+ import type { ProviderTransportFactory } from '@c15t/react';
3
+ import type { UseNetworkBlockerOptions, UsePersistenceOptions, UseScriptLoaderOptions } from '@c15t/react/module-hooks';
4
+ import type { ConsentProviderOptions } from '@c15t/react/provider';
5
+ import type { ReactNode } from 'react';
6
+ import type { ConsentConfig } from './config';
7
+ import type { ConsentState } from './types';
8
+ export interface ConsentRootProps {
9
+ /**
10
+ * The visitor's resolved consent state, produced server-side by
11
+ * `resolveConsent()` from `@c15t/nextjs/server`. Serializable JSON; a
12
+ * promise is fine, the provider awaits it.
13
+ */
14
+ state: ConsentState | Promise<ConsentState>;
15
+ /**
16
+ * Backend base URL (e.g. `/api/c15t` or `https://consent.example.com`).
17
+ * When provided, the provider uses hosted mode and auto-runs init.
18
+ * Overrides `config.backendURL`.
19
+ */
20
+ backendURL?: string;
21
+ /**
22
+ * A `defineConsentConfig` result. Picks the transport when
23
+ * `options.mode` is not set:
24
+ *
25
+ * - `initURL` set: hosted mode with init fetched from that same-origin
26
+ * route (the handlers' `GET`, which resolves the cached manifest with
27
+ * the request's geo) and saves posted to `${backendURL}/subjects`.
28
+ * - Otherwise `manifestURL` set: the manifest transport, resolving init
29
+ * in the browser from that route. The resolver loads on first init so
30
+ * it stays out of the initial bundle.
31
+ * - Otherwise: hosted mode against `backendURL`.
32
+ */
33
+ config?: ConsentConfig;
34
+ /**
35
+ * Script tags to manage with the script-loader module.
36
+ */
37
+ scripts?: Script[];
38
+ /**
39
+ * Remove configured browser data for initially denied categories after policy
40
+ * resolution and when consent is later revoked.
41
+ * Initial-only: remount ConsentRoot to replace the cleanup configuration.
42
+ */
43
+ clearOnRevocation?: ConsentProviderOptions['clearOnRevocation'];
44
+ /**
45
+ * Script-loader options.
46
+ */
47
+ scriptLoader?: UseScriptLoaderOptions;
48
+ /**
49
+ * Network-blocker configuration.
50
+ */
51
+ networkBlocker?: UseNetworkBlockerOptions | false;
52
+ /**
53
+ * Enable client-side persistence. Defaults to true.
54
+ */
55
+ persistence?: boolean | UsePersistenceOptions;
56
+ /**
57
+ * Additional React provider options.
58
+ */
59
+ options?: Omit<ConsentProviderOptions, 'mode' | 'clearOnRevocation' | 'networkBlocker' | 'persistence' | 'prefetch' | 'scriptLoader' | 'scripts' | '__debugPkg'> & {
60
+ mode?: ProviderTransportFactory;
61
+ };
62
+ children: ReactNode;
63
+ }
64
+ /**
65
+ * Mounts the consent provider for a Next.js app. Render it once, near the
66
+ * top of the tree, with the `state` a Server Component resolved through
67
+ * `resolveConsent()`.
68
+ *
69
+ * @example
70
+ * ```tsx
71
+ * // app/layout.tsx
72
+ * import { ConsentRoot } from '@c15t/nextjs';
73
+ * import { resolveConsent } from '@c15t/nextjs/server';
74
+ * import { consentConfig } from '@/consent.config';
75
+ *
76
+ * export default function RootLayout({ children }) {
77
+ * return (
78
+ * <html>
79
+ * <body>
80
+ * <ConsentRoot
81
+ * state={resolveConsent({ config: consentConfig })}
82
+ * config={consentConfig}
83
+ * >
84
+ * {children}
85
+ * </ConsentRoot>
86
+ * </body>
87
+ * </html>
88
+ * );
89
+ * }
90
+ * ```
91
+ */
92
+ export declare const ConsentRoot: ({ state, backendURL, config, scripts, scriptLoader, clearOnRevocation, networkBlocker, persistence, options, children, }: ConsentRootProps) => import("react").JSX.Element;