@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
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- let e="2.2.1";export{e as version};
1
+ let e="3.0.0-alpha.0";export{e as version};
@@ -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,86 @@
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
+ * Script-loader options.
40
+ */
41
+ scriptLoader?: UseScriptLoaderOptions;
42
+ /**
43
+ * Network-blocker configuration.
44
+ */
45
+ networkBlocker?: UseNetworkBlockerOptions | false;
46
+ /**
47
+ * Enable client-side persistence. Defaults to true.
48
+ */
49
+ persistence?: boolean | UsePersistenceOptions;
50
+ /**
51
+ * Additional React provider options.
52
+ */
53
+ options?: Omit<ConsentProviderOptions, 'mode' | 'networkBlocker' | 'persistence' | 'prefetch' | 'scriptLoader' | 'scripts' | '__debugPkg'> & {
54
+ mode?: ProviderTransportFactory;
55
+ };
56
+ children: ReactNode;
57
+ }
58
+ /**
59
+ * Mounts the consent provider for a Next.js app. Render it once, near the
60
+ * top of the tree, with the `state` a Server Component resolved through
61
+ * `resolveConsent()`.
62
+ *
63
+ * @example
64
+ * ```tsx
65
+ * // app/layout.tsx
66
+ * import { ConsentRoot } from '@c15t/nextjs';
67
+ * import { resolveConsent } from '@c15t/nextjs/server';
68
+ * import { consentConfig } from '@/consent.config';
69
+ *
70
+ * export default function RootLayout({ children }) {
71
+ * return (
72
+ * <html>
73
+ * <body>
74
+ * <ConsentRoot
75
+ * state={resolveConsent({ config: consentConfig })}
76
+ * config={consentConfig}
77
+ * >
78
+ * {children}
79
+ * </ConsentRoot>
80
+ * </body>
81
+ * </html>
82
+ * );
83
+ * }
84
+ * ```
85
+ */
86
+ export declare const ConsentRoot: ({ state, backendURL, config, scripts, scriptLoader, networkBlocker, persistence, options, children, }: ConsentRootProps) => import("react").JSX.Element;