@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.
- package/AGENTS.md +103 -142
- package/README.md +4 -4
- package/dist/api.js +1 -0
- package/dist/config.js +1 -0
- package/dist/devtools.js +2 -0
- package/dist/headers.js +1 -0
- package/dist/iab/styles.css +1 -1
- package/dist/iab/styles.tw3.css +27 -19
- package/dist/index.js +1 -1
- package/dist/middleware.js +1 -0
- package/dist/node-bridge.js +1 -0
- package/dist/pages.js +1 -0
- package/dist/proxy.js +1 -0
- package/dist/root.js +2 -0
- package/dist/server.js +1 -0
- package/dist/static.js +1 -0
- package/dist/styles.css +1 -1
- package/dist/styles.tw3.css +67 -29
- package/dist/version.js +1 -1
- package/dist-types/api.d.ts +88 -0
- package/dist-types/config.d.ts +110 -0
- package/dist-types/devtools.d.ts +1 -0
- package/dist-types/headers.d.ts +4 -0
- package/dist-types/index.d.ts +28 -10
- package/dist-types/middleware.d.ts +15 -0
- package/dist-types/node-bridge.d.ts +57 -0
- package/dist-types/pages.d.ts +88 -0
- package/dist-types/proxy.d.ts +34 -0
- package/dist-types/root.d.ts +92 -0
- package/dist-types/server.d.ts +164 -0
- package/dist-types/static.d.ts +42 -0
- package/dist-types/types.d.ts +5 -36
- package/dist-types/version.d.ts +1 -1
- package/docs/README.md +103 -142
- package/docs/assets/v3/brand-bar.png +0 -0
- package/docs/assets/v3/brand-card.png +0 -0
- package/docs/assets/v3/choice-wall.png +0 -0
- package/docs/assets/v3/mobile-card.png +0 -0
- package/docs/assets/v3/preferences.png +0 -0
- package/docs/customization/overview.md +45 -0
- package/docs/customization/recipes.md +79 -0
- package/docs/customization/slots.md +55 -0
- package/docs/customization/tokens.md +76 -0
- package/docs/customization/translations.md +49 -0
- package/docs/frameworks/next/api-reference/data-fetching.md +416 -0
- package/docs/frameworks/next/app-router.md +403 -0
- package/docs/frameworks/next/client-side.md +118 -0
- package/docs/frameworks/next/components/consent-banner.md +251 -211
- package/docs/frameworks/next/components/consent-dialog-link.md +96 -35
- package/docs/frameworks/next/components/consent-dialog-trigger.md +74 -149
- package/docs/frameworks/next/components/consent-dialog.md +189 -134
- package/docs/frameworks/next/components/consent-manager-provider.md +68 -318
- package/docs/frameworks/next/components/consent-widget.md +172 -114
- package/docs/frameworks/next/components/dev-tools.md +199 -40
- package/docs/frameworks/next/components/frame.md +137 -42
- package/docs/frameworks/next/concepts/consent-categories.md +24 -89
- package/docs/frameworks/next/concepts/policy-presets.md +142 -0
- package/docs/frameworks/next/content-security-policy.md +189 -0
- package/docs/frameworks/next/data-fetching.md +74 -0
- package/docs/frameworks/next/geography-headers.md +251 -0
- package/docs/frameworks/next/headless.md +95 -185
- package/docs/frameworks/next/hooks/use-consent-manager/overview.md +42 -163
- package/docs/frameworks/next/iab/overview.md +37 -107
- package/docs/frameworks/next/optimization.md +158 -194
- package/docs/frameworks/next/pages-router.md +296 -0
- package/docs/frameworks/next/quickstart.md +31 -132
- package/docs/frameworks/next/script-loader.md +140 -465
- package/docs/frameworks/next/server-side.md +97 -130
- package/docs/frameworks/next/static-export.md +164 -0
- package/docs/frameworks/next/styling/overview.md +174 -248
- package/docs/frameworks/next/troubleshooting.md +134 -144
- package/docs/guides/consent-state.md +60 -0
- package/docs/guides/data-fetching.md +163 -0
- package/docs/guides/deployment-modes.md +63 -0
- package/docs/guides/troubleshooting.md +68 -0
- package/docs/guides/verify-consent.md +62 -0
- package/docs/integrations/adobe-analytics.md +239 -105
- package/docs/integrations/ahrefs-analytics.md +238 -104
- package/docs/integrations/amplitude.md +219 -157
- package/docs/integrations/building-integrations.md +32 -224
- package/docs/integrations/clear-on-revocation.md +167 -0
- package/docs/integrations/clearbit.md +247 -86
- package/docs/integrations/cloudflare-web-analytics.md +250 -84
- package/docs/integrations/crisp.md +251 -97
- package/docs/integrations/databuddy.md +259 -153
- package/docs/integrations/fathom-analytics.md +239 -96
- package/docs/integrations/google-maps.md +328 -207
- package/docs/integrations/google-tag-manager.md +248 -96
- package/docs/integrations/google-tag.md +261 -90
- package/docs/integrations/heap.md +222 -149
- package/docs/integrations/hightouch.md +225 -131
- package/docs/integrations/hotjar.md +239 -90
- package/docs/integrations/intercom.md +239 -98
- package/docs/integrations/linkedin-insights.md +243 -113
- package/docs/integrations/logrocket.md +241 -123
- package/docs/integrations/matomo-analytics.md +256 -111
- package/docs/integrations/meta-pixel.md +197 -324
- package/docs/integrations/microsoft-clarity.md +233 -114
- package/docs/integrations/microsoft-uet.md +245 -110
- package/docs/integrations/mixpanel-analytics.md +252 -87
- package/docs/integrations/openai-pixel.md +441 -0
- package/docs/integrations/overview.md +95 -133
- package/docs/integrations/pirsch.md +249 -96
- package/docs/integrations/plausible-analytics.md +241 -100
- package/docs/integrations/posthog.md +353 -214
- package/docs/integrations/promptwatch.md +251 -81
- package/docs/integrations/reddit-pixel.md +226 -173
- package/docs/integrations/rudderstack.md +244 -187
- package/docs/integrations/rybbit-analytics.md +244 -91
- package/docs/integrations/segment.md +238 -92
- package/docs/integrations/snapchat-pixel.md +240 -110
- package/docs/integrations/tiktok-pixel.md +249 -81
- package/docs/integrations/umami-analytics.md +242 -95
- package/docs/integrations/vercel-analytics.md +242 -90
- package/docs/integrations/x-pixel.md +238 -104
- package/docs/integrations/youtube.md +354 -142
- package/docs/upgrade-v3.md +334 -0
- package/iab/styles.css +1 -1
- package/iab/styles.tw3.css +1 -1
- package/package.json +106 -65
- package/readme.json +3 -3
- package/src/iab/styles.css +1 -1
- package/src/iab/styles.tw3.css +1 -1
- package/src/styles.css +1 -1
- package/src/styles.tw3.css +1 -1
- package/styles.css +1 -1
- package/styles.tw3.css +1 -1
- package/client/components/consent-dialog-link.js +0 -3
- package/client/components/integrations.js +0 -3
- package/dist/components/integrations/index.cjs +0 -1
- package/dist/components/integrations/index.js +0 -1
- package/dist/headless.cjs +0 -1
- package/dist/index.cjs +0 -1
- package/dist/libs/browser-initial-data.cjs +0 -1
- package/dist/libs/browser-initial-data.js +0 -1
- package/dist/libs/initial-data.cjs +0 -1
- package/dist/libs/initial-data.js +0 -1
- package/dist/types.cjs +0 -1
- package/dist/version.cjs +0 -1
- package/dist-types/components/integrations/index.d.ts +0 -1
- package/dist-types/libs/browser-initial-data.d.ts +0 -9
- package/dist-types/libs/initial-data.d.ts +0 -33
- package/docs/frameworks/next/building-headless-components.md +0 -379
- package/docs/frameworks/next/callbacks.md +0 -186
- package/docs/frameworks/next/concepts/client-modes.md +0 -177
- package/docs/frameworks/next/concepts/consent-models.md +0 -117
- package/docs/frameworks/next/concepts/cookie-management.md +0 -122
- package/docs/frameworks/next/concepts/glossary.md +0 -24
- package/docs/frameworks/next/concepts/initialization-flow.md +0 -149
- package/docs/frameworks/next/concepts/policy-packs.md +0 -230
- package/docs/frameworks/next/hooks/use-color-scheme.md +0 -41
- package/docs/frameworks/next/hooks/use-consent-manager/checking-consent.md +0 -96
- package/docs/frameworks/next/hooks/use-consent-manager/location-info.md +0 -97
- package/docs/frameworks/next/hooks/use-consent-manager/setting-consent.md +0 -94
- package/docs/frameworks/next/hooks/use-draggable.md +0 -59
- package/docs/frameworks/next/hooks/use-focus-trap.md +0 -42
- package/docs/frameworks/next/hooks/use-reduced-motion.md +0 -37
- package/docs/frameworks/next/hooks/use-ssr-status.md +0 -32
- package/docs/frameworks/next/hooks/use-text-direction.md +0 -50
- package/docs/frameworks/next/hooks/use-translations.md +0 -55
- package/docs/frameworks/next/iab/consent-banner.md +0 -91
- package/docs/frameworks/next/iab/consent-dialog.md +0 -129
- package/docs/frameworks/next/iab/use-gvl-data.md +0 -21
- package/docs/frameworks/next/iframe-blocking.md +0 -106
- package/docs/frameworks/next/internationalization.md +0 -207
- package/docs/frameworks/next/network-blocker.md +0 -140
- package/docs/frameworks/next/policy-packs.md +0 -248
- package/docs/frameworks/next/styling/classnames.md +0 -94
- package/docs/frameworks/next/styling/color-scheme.md +0 -84
- package/docs/frameworks/next/styling/css-variables.md +0 -53
- package/docs/frameworks/next/styling/slots.md +0 -94
- package/docs/frameworks/next/styling/tailwind.md +0 -137
- package/docs/frameworks/next/styling/tokens.md +0 -156
- package/docs/shared/concepts/client-modes.md +0 -103
- package/docs/shared/concepts/consent-categories.md +0 -41
- package/docs/shared/concepts/consent-models.md +0 -72
- package/docs/shared/concepts/cookie-management.md +0 -88
- package/docs/shared/concepts/glossary.md +0 -24
- package/docs/shared/concepts/initialization-flow.md +0 -105
- package/docs/shared/concepts/policy-packs.md +0 -225
- package/docs/shared/react/components/consent-banner.md +0 -242
- package/docs/shared/react/components/consent-dialog-link.md +0 -45
- package/docs/shared/react/components/consent-dialog-trigger.md +0 -185
- package/docs/shared/react/components/consent-dialog.md +0 -119
- package/docs/shared/react/components/consent-manager-provider.md +0 -225
- package/docs/shared/react/components/consent-widget.md +0 -121
- package/docs/shared/react/components/dev-tools.md +0 -81
- package/docs/shared/react/components/frame.md +0 -52
- package/docs/shared/react/guides/building-headless-components.md +0 -110
- package/docs/shared/react/guides/callbacks.md +0 -89
- package/docs/shared/react/guides/headless.md +0 -31
- package/docs/shared/react/guides/iframe-blocking.md +0 -65
- package/docs/shared/react/guides/internationalization.md +0 -123
- package/docs/shared/react/guides/network-blocker.md +0 -72
- package/docs/shared/react/guides/optimization.md +0 -44
- package/docs/shared/react/guides/policy-packs.md +0 -173
- package/docs/shared/react/guides/script-loader.md +0 -311
- package/docs/shared/react/hooks/use-color-scheme.md +0 -31
- package/docs/shared/react/hooks/use-consent-manager/checking-consent.md +0 -95
- package/docs/shared/react/hooks/use-consent-manager/location-info.md +0 -96
- package/docs/shared/react/hooks/use-consent-manager/overview.md +0 -74
- package/docs/shared/react/hooks/use-consent-manager/setting-consent.md +0 -93
- package/docs/shared/react/hooks/use-draggable.md +0 -30
- package/docs/shared/react/hooks/use-focus-trap.md +0 -20
- package/docs/shared/react/hooks/use-reduced-motion.md +0 -33
- package/docs/shared/react/hooks/use-ssr-status.md +0 -16
- package/docs/shared/react/hooks/use-text-direction.md +0 -38
- package/docs/shared/react/hooks/use-translations.md +0 -15
- package/docs/shared/react/iab/consent-banner.md +0 -60
- package/docs/shared/react/iab/consent-dialog.md +0 -76
- package/docs/shared/react/iab/overview.md +0 -80
- package/docs/shared/react/iab/use-gvl-data.md +0 -21
- package/docs/shared/react/styling/classnames.md +0 -93
- package/docs/shared/react/styling/color-scheme.md +0 -35
- package/docs/shared/react/styling/css-variables.md +0 -53
- package/docs/shared/react/styling/overview.md +0 -261
- package/docs/shared/react/styling/slots.md +0 -93
- package/docs/shared/react/styling/stylesheet-entrypoint.md +0 -8
- package/docs/shared/react/styling/tailwind.md +0 -88
- package/docs/shared/react/styling/tokens.md +0 -155
- 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';
|
package/dist-types/index.d.ts
CHANGED
|
@@ -1,14 +1,32 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
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
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
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 {
|
|
12
|
-
export {
|
|
13
|
-
export {
|
|
14
|
-
export type {
|
|
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;
|