@c15t/react 3.0.0-alpha.9 → 3.0.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.
- package/AGENTS.md +7 -9
- package/README.md +41 -70
- package/SKILL.md +1 -1
- package/dist/aggregate-components.js +1 -1
- package/dist/components/consent-gate/atoms.js +1 -1
- package/dist/components/consent-gate/frame.js +2 -0
- package/dist/components/consent-gate/index.js +1 -1
- package/dist/components/iab-panel/atoms/root.js +1 -1
- package/dist/components/iab-panel/iab-panel.js +1 -1
- package/dist/components/iab-prompt/atoms/root.js +1 -1
- package/dist/components/iab-prompt/iab-prompt.js +1 -1
- package/dist/components/panel/atoms/root.js +1 -1
- package/dist/components/panel-trigger/atoms/root.js +1 -1
- package/dist/components/panel-trigger/panel-trigger.js +1 -1
- package/dist/components/panel-trigger/toolbar-loader.js +2 -0
- package/dist/components/preferences/atoms/root.js +1 -1
- package/dist/components/prompt/atoms/early-tap-script.js +2 -0
- package/dist/components/prompt/atoms/root.js +1 -1
- package/dist/components/shared/primitives/button.js +1 -1
- package/dist/components/shared/surface-styles.js +1 -1
- package/dist/consent-gate.js +1 -1
- package/dist/context/index.js +1 -1
- package/dist/devtools.js +1 -1
- package/dist/iab/styles.tw3.css +2 -2
- package/dist/iab-dialog-deferred.js +2 -0
- package/dist/iab.js +1 -1
- package/dist/index-parts/consent-gate.js +1 -1
- package/dist/index-parts/core.js +1 -1
- package/dist/index-parts/frame.js +1 -0
- package/dist/index-parts/hosted.js +1 -0
- package/dist/index-parts/offline.js +1 -0
- package/dist/index-parts/presets.js +1 -0
- package/dist/index.js +1 -1
- package/dist/modes.js +1 -0
- package/dist/panel-link.js +1 -1
- package/dist/panel-trigger.js +1 -1
- package/dist/provider.js +1 -1
- package/dist/styles.tw3.css +2 -2
- package/dist/transports/hosted.js +1 -0
- package/dist/transports/manifest.js +1 -0
- package/dist/utils/deferred-module.js +1 -1
- package/dist/version.js +1 -1
- package/dist-types/chunk-warming.d.ts +7 -6
- package/dist-types/components/consent-gate/frame.d.ts +19 -0
- package/dist-types/components/consent-gate/index.d.ts +3 -19
- package/dist-types/components/iab-prompt/iab-prompt.d.ts +1 -1
- package/dist-types/components/panel/index.d.ts +1 -1
- package/dist-types/components/panel-trigger/toolbar-loader.d.ts +34 -0
- package/dist-types/components/preferences/index.d.ts +1 -1
- package/dist-types/components/prompt/atoms/early-tap-script.d.ts +17 -0
- package/dist-types/components/prompt/index.d.ts +1 -1
- package/dist-types/components/shared/surface-styles.d.ts +26 -2
- package/dist-types/consent-gate.d.ts +1 -1
- package/dist-types/context/index.d.ts +3 -3
- package/dist-types/context.d.ts +2 -0
- package/dist-types/gpp.d.ts +1 -1
- package/dist-types/iab-dialog-deferred.d.ts +36 -0
- package/dist-types/iab.d.ts +3 -2
- package/dist-types/index-parts/consent-gate.d.ts +1 -1
- package/dist-types/index-parts/core.d.ts +1 -2
- package/dist-types/index-parts/frame.d.ts +7 -0
- package/dist-types/index-parts/hosted.d.ts +7 -0
- package/dist-types/index-parts/offline.d.ts +7 -0
- package/dist-types/index-parts/presets.d.ts +7 -0
- package/dist-types/index.d.ts +5 -1
- package/dist-types/modes.d.ts +26 -0
- package/dist-types/panel-link.d.ts +1 -1
- package/dist-types/panel-trigger.d.ts +1 -1
- package/dist-types/provider.d.ts +3 -3
- package/dist-types/transports/hosted.d.ts +36 -0
- package/dist-types/transports/manifest.d.ts +48 -0
- package/dist-types/version.d.ts +1 -1
- package/docs/README.md +7 -9
- package/docs/concepts/choose-your-setup.md +45 -10
- package/docs/concepts/consent-categories.md +1 -1
- package/docs/concepts/consent-state.md +5 -2
- package/docs/concepts/data-fetching.md +100 -42
- package/docs/concepts/modes.md +281 -0
- package/docs/customization/dark-mode.md +1 -1
- package/docs/customization/motion.md +2 -2
- package/docs/customization/recipes.md +4 -4
- package/docs/customization/slots.md +25 -25
- package/docs/customization/stylesheets.md +12 -14
- package/docs/customization/tailwind.md +17 -11
- package/docs/customization/tokens.md +36 -7
- package/docs/frameworks/react/components/consent-banner.md +14 -10
- package/docs/frameworks/react/components/consent-dialog.md +14 -10
- package/docs/frameworks/react/components/consent-provider.md +51 -44
- package/docs/frameworks/react/components.md +14 -10
- package/docs/frameworks/react/content-security-policy.md +21 -12
- package/docs/frameworks/react/hooks.md +2 -2
- package/docs/frameworks/react/iab.md +20 -2
- package/docs/frameworks/react/quickstart.md +63 -97
- package/docs/frameworks/react/rendering.md +168 -94
- package/docs/frameworks/react/scripts.md +19 -28
- package/docs/frameworks/react/troubleshooting.md +57 -25
- package/docs/frameworks/react/upgrade-v3.md +110 -62
- package/docs/guides/banner-experiments.md +21 -6
- package/docs/guides/troubleshooting.md +89 -25
- package/docs/guides/verify-consent.md +23 -8
- package/docs/integrations/adobe-analytics.md +60 -64
- package/docs/integrations/ahrefs-analytics.md +58 -63
- package/docs/integrations/amplitude.md +60 -64
- package/docs/integrations/clearbit.md +59 -63
- package/docs/integrations/cloudflare-web-analytics.md +56 -60
- package/docs/integrations/cloudflare-zaraz.md +55 -57
- package/docs/integrations/crisp.md +64 -69
- package/docs/integrations/databuddy.md +62 -64
- package/docs/integrations/fathom-analytics.md +56 -60
- package/docs/integrations/front-chat.md +56 -60
- package/docs/integrations/google-maps.md +25 -13
- package/docs/integrations/google-tag-manager.md +153 -77
- package/docs/integrations/google-tag.md +134 -78
- package/docs/integrations/heap.md +56 -60
- package/docs/integrations/hightouch.md +55 -60
- package/docs/integrations/hotjar.md +60 -64
- package/docs/integrations/intercom.md +55 -60
- package/docs/integrations/klaviyo.md +65 -66
- package/docs/integrations/linkedin-insights.md +58 -63
- package/docs/integrations/logrocket.md +55 -60
- package/docs/integrations/matomo-analytics.md +58 -60
- package/docs/integrations/meta-pixel.md +56 -60
- package/docs/integrations/microsoft-clarity.md +57 -60
- package/docs/integrations/microsoft-uet.md +58 -61
- package/docs/integrations/mixpanel-analytics.md +73 -75
- package/docs/integrations/one-dollar-stats.md +53 -59
- package/docs/integrations/openai-pixel.md +58 -60
- package/docs/integrations/overview.md +59 -42
- package/docs/integrations/pinterest-tag.md +56 -60
- package/docs/integrations/pirsch.md +54 -60
- package/docs/integrations/plausible-analytics.md +55 -60
- package/docs/integrations/posthog.md +56 -60
- package/docs/integrations/promptwatch.md +57 -63
- package/docs/integrations/reddit-pixel.md +57 -60
- package/docs/integrations/rudderstack.md +65 -67
- package/docs/integrations/rybbit-analytics.md +70 -75
- package/docs/integrations/segment.md +56 -60
- package/docs/integrations/sentry.md +65 -60
- package/docs/integrations/snapchat-pixel.md +54 -60
- package/docs/integrations/tiktok-pixel.md +59 -63
- package/docs/integrations/umami-analytics.md +54 -60
- package/docs/integrations/vercel-analytics.md +53 -59
- package/docs/integrations/vercel-speed-insights.md +317 -0
- package/docs/integrations/x-pixel.md +57 -63
- package/docs/integrations/youtube.md +25 -13
- package/package.json +18 -8
- package/docs/upgrade-v3.md +0 -429
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeps a banner tap made before hydration.
|
|
3
|
+
*
|
|
4
|
+
* A server-rendered banner shows long before React attaches its handlers.
|
|
5
|
+
* The inline script records an accept, reject, dismiss or customize tap in
|
|
6
|
+
* that gap and hides the banner. Once this component mounts, the banner's
|
|
7
|
+
* own handlers work: it stops the script and records the tap when the
|
|
8
|
+
* runtime has started. See `@c15t/core/surface-actions`.
|
|
9
|
+
*
|
|
10
|
+
* The script is in the server HTML. A banner that hydrates keeps it, inert
|
|
11
|
+
* once claimed, so hydration changes nothing in the markup. A banner React
|
|
12
|
+
* renders in the browser has its handlers at once, and a script it inserts
|
|
13
|
+
* would never run, so there it renders nothing.
|
|
14
|
+
*
|
|
15
|
+
* @internal
|
|
16
|
+
*/
|
|
17
|
+
export declare const EarlyTapScript: () => import("react").JSX.Element | null;
|
|
@@ -62,7 +62,7 @@ export interface ConsentBannerCompoundComponent extends FC<ConsentBannerProps> {
|
|
|
62
62
|
* ```tsx
|
|
63
63
|
* <ConsentProvider
|
|
64
64
|
* options={{
|
|
65
|
-
* mode: hosted({
|
|
65
|
+
* mode: hosted({ backendURL: '/api/c15t' }),
|
|
66
66
|
* i18n: {
|
|
67
67
|
* locale: 'en',
|
|
68
68
|
* messages: {
|
|
@@ -2,9 +2,33 @@
|
|
|
2
2
|
export interface SurfaceStyleSheet {
|
|
3
3
|
/** Dedupes the stylesheet: a page renders each `id` once. */
|
|
4
4
|
id: string;
|
|
5
|
-
/** The stylesheet text. */
|
|
5
|
+
/** The stylesheet text. Empty for a deferred sheet. */
|
|
6
6
|
css: string;
|
|
7
|
+
/**
|
|
8
|
+
* Loads the text of a deferred sheet. A browser bundle gets one in place
|
|
9
|
+
* of `css` when the framework already put the sheet in the server HTML,
|
|
10
|
+
* as the Next.js adapter does, so the text ships once.
|
|
11
|
+
*/
|
|
12
|
+
load?: () => Promise<string>;
|
|
7
13
|
}
|
|
14
|
+
/**
|
|
15
|
+
* Starts loading the deferred sheets the page does not hold yet. Safe to
|
|
16
|
+
* call often: each sheet loads once, and the next call retries a failed
|
|
17
|
+
* load.
|
|
18
|
+
*
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export declare const preloadSurfaceSheets: (sheets: readonly SurfaceStyleSheet[]) => Promise<void>;
|
|
22
|
+
/**
|
|
23
|
+
* Whether a surface can show: its deferred sheets are in the page or
|
|
24
|
+
* loaded. Starts loading the missing ones after mount, so a surface that
|
|
25
|
+
* renders later, like a banner waiting on the browser's consent fetch,
|
|
26
|
+
* finds them ready. Hydration reads `true`: the server rendered the sheets
|
|
27
|
+
* it rendered the surface with.
|
|
28
|
+
*
|
|
29
|
+
* @internal
|
|
30
|
+
*/
|
|
31
|
+
export declare const useSurfaceSheetsReady: (sheets: readonly SurfaceStyleSheet[], noStyle?: boolean) => boolean;
|
|
8
32
|
/**
|
|
9
33
|
* Renders the stylesheets a stock surface needs as `<style>` elements.
|
|
10
34
|
*
|
|
@@ -33,4 +57,4 @@ export interface SurfaceStyleSheet {
|
|
|
33
57
|
export declare const SurfaceStyles: ({ sheets, noStyle, }: {
|
|
34
58
|
sheets: readonly SurfaceStyleSheet[];
|
|
35
59
|
noStyle?: boolean;
|
|
36
|
-
}) => import("react").JSX.Element[] | null;
|
|
60
|
+
}) => (import("react").JSX.Element | null)[] | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { ConsentGate, ConsentGateButton, type ConsentGateCompoundComponent, type ConsentGateProps, ConsentGateRoot, ConsentGateTitle, Frame, FrameButton, type FrameCompoundComponent, type FrameProps, FrameRoot, FrameTitle, } from './components/consent-gate/index.js';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
1
|
+
export { HydrationSnapshotContext, KernelContext, type ProviderServices, ProviderServicesContext, StreamedPrefetchContext, } from '../context.js';
|
|
2
|
+
export { ConsentTrackingContext, type ConsentTrackingValue, toSaveUISource, useConsentTracking, } from './consent-tracking-context.js';
|
|
3
|
+
export { GlobalThemeContext, LocalThemeContext, type ThemeContextValue, } from './theme-context.js';
|
package/dist-types/context.d.ts
CHANGED
|
@@ -14,6 +14,8 @@ export interface ProviderServices {
|
|
|
14
14
|
clearRecords: () => void;
|
|
15
15
|
getPresentation: () => ConsentPresentation | undefined;
|
|
16
16
|
getConsentCategories: () => readonly AllConsentNames[];
|
|
17
|
+
/** Whether the runtime has started: records hydrated, prefetch adopted. */
|
|
18
|
+
isStarted: () => boolean;
|
|
17
19
|
/**
|
|
18
20
|
* Store a language override and load its copy: init runs again on the
|
|
19
21
|
* provider's own kernel while it is enabled, and a borrowed runtime
|
package/dist-types/gpp.d.ts
CHANGED
|
@@ -18,7 +18,7 @@ export type ConsentGPPProps = RuntimeGPPOptions;
|
|
|
18
18
|
* ```tsx
|
|
19
19
|
* import { ConsentGPP } from '@c15t/react/gpp';
|
|
20
20
|
*
|
|
21
|
-
* <ConsentProvider options={{ mode: hosted({
|
|
21
|
+
* <ConsentProvider options={{ mode: hosted({ backendURL }) }}>
|
|
22
22
|
* <ConsentGPP usFallback="none" />
|
|
23
23
|
* <App />
|
|
24
24
|
* </ConsentProvider>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { IABConsentDialogCompoundComponent } from './components/iab-panel/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* The IAB TCF preference centre: purposes, stacks, special features and
|
|
4
|
+
* per-vendor consent and legitimate-interest controls.
|
|
5
|
+
*
|
|
6
|
+
* @remarks
|
|
7
|
+
* The component code loads on demand. It downloads in the browser's first
|
|
8
|
+
* idle period after the page's `load` event while the IAB banner is shown,
|
|
9
|
+
* on hover or focus of the banner's Customize button or partners link, or
|
|
10
|
+
* when the dialog opens, whichever comes first. `preloadDialog: 'intent'` in
|
|
11
|
+
* the provider options skips the idle load. `open={true}` or `showTrigger`
|
|
12
|
+
* loads it on mount under a model `models` lists; under another model,
|
|
13
|
+
* `showTrigger` loads only the trigger.
|
|
14
|
+
*
|
|
15
|
+
* The compound parts (`IABConsentDialog.Root`, `.Card`, `.Header`, `.Tabs`,
|
|
16
|
+
* `.TabButton`, `.Content`, `.Footer`, `.Overlay`, `.FeatureItem`,
|
|
17
|
+
* `.PurposeItem`, `.StackItem`, `.VendorList`) load the same module when
|
|
18
|
+
* they render.
|
|
19
|
+
*
|
|
20
|
+
* @example
|
|
21
|
+
* ```tsx
|
|
22
|
+
* <IABProvider cmpId={28}>
|
|
23
|
+
* <IABConsentBanner />
|
|
24
|
+
* <IABConsentDialog />
|
|
25
|
+
* </IABProvider>
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export declare const IABConsentDialog: IABConsentDialogCompoundComponent;
|
|
31
|
+
/**
|
|
32
|
+
* Reset the warming state shared by mounted dialogs between tests.
|
|
33
|
+
*
|
|
34
|
+
* @internal
|
|
35
|
+
*/
|
|
36
|
+
export declare const resetIABDialogWarmingForTests: () => void;
|
package/dist-types/iab.d.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* import { IABProvider, IABConsentBanner, IABConsentDialog } from '@c15t/react/iab';
|
|
13
13
|
*
|
|
14
14
|
* <ConsentProvider
|
|
15
|
-
* options={{ mode: hosted({
|
|
15
|
+
* options={{ mode: hosted({ backendURL: '/api/c15t' }) }}
|
|
16
16
|
* >
|
|
17
17
|
* <IABProvider cmpId={28}>
|
|
18
18
|
* <IABConsentBanner />
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
* @packageDocumentation
|
|
25
25
|
*/
|
|
26
26
|
export { IABConsentBanner, type IABConsentBannerProps, } from './components/iab-prompt/index.js';
|
|
27
|
-
export {
|
|
27
|
+
export type { IABConsentDialogProps } from './components/iab-panel/index.js';
|
|
28
|
+
export { IABConsentDialog } from './iab-dialog-deferred.js';
|
|
28
29
|
export { type HeadlessIABBannerAction, type HeadlessIABBannerState, type HeadlessIABDialogAction, type HeadlessIABDialogState, type HeadlessIABPreferenceTab, type UseHeadlessIABConsentUIResult, useHeadlessIABConsentUI, } from './hooks/use-headless-iab-consent-ui.js';
|
|
29
30
|
export { IABProvider } from './iab-context.js';
|
|
30
31
|
export type { IABProviderProps } from './iab-context.js';
|
|
@@ -4,4 +4,4 @@
|
|
|
4
4
|
* (esbuild) does not treat every module the index names as part of an app
|
|
5
5
|
* that imports one hook: only the groups it uses are live.
|
|
6
6
|
*/
|
|
7
|
-
export { ConsentGate
|
|
7
|
+
export { ConsentGate } from '../components/consent-gate/index.js';
|
|
@@ -4,5 +4,4 @@
|
|
|
4
4
|
* (esbuild) does not treat every module the index names as part of an app
|
|
5
5
|
* that imports one hook: only the groups it uses are live.
|
|
6
6
|
*/
|
|
7
|
-
export { createConsentKernel, custom
|
|
8
|
-
export { offline } from '../transports/offline.js';
|
|
7
|
+
export { createConsentKernel, custom } from '@c15t/core';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One group of `@c15t/react`'s public exports. The package index re-exports
|
|
3
|
+
* each group with `export *`, so a bundler that splits code by reachability
|
|
4
|
+
* (esbuild) does not treat every module the index names as part of an app
|
|
5
|
+
* that imports one hook: only the groups it uses are live.
|
|
6
|
+
*/
|
|
7
|
+
export { Frame } from '../components/consent-gate/frame.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One group of `@c15t/react`'s public exports. The package index re-exports
|
|
3
|
+
* each group with `export *`, so a bundler that splits code by reachability
|
|
4
|
+
* (esbuild) does not treat every module the index names as part of an app
|
|
5
|
+
* that imports one hook: only the groups it uses are live.
|
|
6
|
+
*/
|
|
7
|
+
export { hosted } from '@c15t/core';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One group of `@c15t/react`'s public exports. The package index re-exports
|
|
3
|
+
* each group with `export *`, so a bundler that splits code by reachability
|
|
4
|
+
* (esbuild) does not treat every module the index names as part of an app
|
|
5
|
+
* that imports one hook: only the groups it uses are live.
|
|
6
|
+
*/
|
|
7
|
+
export { offline } from '../transports/offline.js';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One group of `@c15t/react`'s public exports. The package index re-exports
|
|
3
|
+
* each group with `export *`, so a bundler that splits code by reachability
|
|
4
|
+
* (esbuild) does not treat every module the index names as part of an app
|
|
5
|
+
* that imports one hook: only the groups it uses are live.
|
|
6
|
+
*/
|
|
7
|
+
export { policyRulePresets } from '@c15t/core';
|
package/dist-types/index.d.ts
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
*
|
|
12
12
|
* function App({ children }) {
|
|
13
13
|
* return (
|
|
14
|
-
* <ConsentProvider options={{ mode: hosted({
|
|
14
|
+
* <ConsentProvider options={{ mode: hosted({ backendURL: '/api/c15t' }) }}>
|
|
15
15
|
* {children}
|
|
16
16
|
* </ConsentProvider>
|
|
17
17
|
* );
|
|
@@ -48,11 +48,15 @@ export type { ConsentBannerCompoundComponent } from './components/prompt/index.j
|
|
|
48
48
|
export type { ReactUIOptions } from './types/manager.js';
|
|
49
49
|
export type { ConsentPresentation, PromptPresentation, PreferencesPresentation, PresentationAction, PromptPosition, PromptVariant, ResolvedConsentPresentation, } from '@c15t/core';
|
|
50
50
|
export * from './index-parts/core.js';
|
|
51
|
+
export * from './index-parts/hosted.js';
|
|
52
|
+
export * from './index-parts/offline.js';
|
|
53
|
+
export * from './index-parts/presets.js';
|
|
51
54
|
export * from './index-parts/consent-dialog.js';
|
|
52
55
|
export * from './index-parts/consent-banner.js';
|
|
53
56
|
export * from './index-parts/consent-dialog-link.js';
|
|
54
57
|
export * from './index-parts/consent-dialog-trigger.js';
|
|
55
58
|
export * from './index-parts/consent-gate.js';
|
|
59
|
+
export * from './index-parts/frame.js';
|
|
56
60
|
export * from './index-parts/draft.js';
|
|
57
61
|
export * from './index-parts/translations.js';
|
|
58
62
|
export * from './index-parts/module-hooks.js';
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@c15t/react/modes` — the single-page app modes, defaulting to what the
|
|
3
|
+
* build integration downloaded.
|
|
4
|
+
*
|
|
5
|
+
* `manifest()` and `hosted()` here read `@c15t/core/generated`, which
|
|
6
|
+
* `consentManifest()` from `c15t/build` fills with the policy snapshot and
|
|
7
|
+
* the backend URL. `c15t/react` exports these in place of the plain
|
|
8
|
+
* `hosted()` from `@c15t/react`.
|
|
9
|
+
*
|
|
10
|
+
* The package index does not import this module. Server-framework packages
|
|
11
|
+
* re-export the index, and their browser bundles must not import
|
|
12
|
+
* `@c15t/core/generated`: Next.js fails the build when they do.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* ```tsx
|
|
16
|
+
* import { ConsentProvider, manifest } from 'c15t/react';
|
|
17
|
+
*
|
|
18
|
+
* <ConsentProvider options={{ mode: manifest() }}>{children}</ConsentProvider>;
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export { hosted } from './transports/hosted.js';
|
|
22
|
+
export type { HostedOptions } from './transports/hosted.js';
|
|
23
|
+
export { manifest } from './transports/manifest.js';
|
|
24
|
+
export type { BrowserManifestModeFactory, ManifestModeOptions, } from './transports/manifest.js';
|
|
25
|
+
export { offline } from './transports/offline.js';
|
|
26
|
+
export type { OfflineModeOptions } from './transports/offline.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { ConsentDialogLink, type ConsentDialogLinkProps, } from './components/panel-link/index.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export { ConsentDialogTrigger, type ConsentDialogTriggerCompound, type ConsentDialogTriggerProps, ConsentDialogTriggerToolbar, type ConsentDialogTriggerToolbarAction, type ConsentDialogTriggerToolbarPreferences, type ConsentDialogTriggerToolbarProps, type CornerPosition, TriggerButton, type TriggerButtonProps, TriggerIcon, type TriggerIconProps, type TriggerIconType, type TriggerOrientation, TriggerRoot, type TriggerRootProps, type TriggerSize, TriggerText, type TriggerTextProps, type TriggerVisibility, type UseDraggableOptions, type UseDraggableReturn, useDraggable, useTriggerContext, } from './components/panel-trigger/index.js';
|
package/dist-types/provider.d.ts
CHANGED
|
@@ -75,7 +75,7 @@ export interface ConsentProviderOptions extends ConsentControlOptions, Pick<Reac
|
|
|
75
75
|
* ```tsx
|
|
76
76
|
* import { ConsentProvider, hosted, offline } from '@c15t/react';
|
|
77
77
|
*
|
|
78
|
-
* <ConsentProvider options={{ mode: hosted({
|
|
78
|
+
* <ConsentProvider options={{ mode: hosted({ backendURL: '/api/c15t' }) }}>
|
|
79
79
|
* {children}
|
|
80
80
|
* </ConsentProvider>
|
|
81
81
|
*
|
|
@@ -119,7 +119,7 @@ export interface ConsentProviderOptions extends ConsentControlOptions, Pick<Reac
|
|
|
119
119
|
* // app/layout.tsx — stays synchronous, so the shell prerenders.
|
|
120
120
|
* const config = resolveConsent({ backendURL });
|
|
121
121
|
* return (
|
|
122
|
-
* <ConsentProvider options={{ mode: hosted({
|
|
122
|
+
* <ConsentProvider options={{ mode: hosted({ backendURL }), prefetch: config }}>
|
|
123
123
|
* {children}
|
|
124
124
|
* </ConsentProvider>
|
|
125
125
|
* );
|
|
@@ -279,7 +279,7 @@ export type ConsentProviderProps = OwnedRuntimeProviderProps | ExternalRuntimePr
|
|
|
279
279
|
* ```tsx
|
|
280
280
|
* import { createConsentRuntime } from '@c15t/core/runtime';
|
|
281
281
|
*
|
|
282
|
-
* const runtime = createConsentRuntime({ mode: hosted({
|
|
282
|
+
* const runtime = createConsentRuntime({ mode: hosted({ backendURL: '/api/c15t' }) });
|
|
283
283
|
* runtime.start();
|
|
284
284
|
*
|
|
285
285
|
* <ConsentProvider runtime={runtime} options={{ theme }}>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { HostedModeFactory, HostedModeOptions } from '@c15t/core';
|
|
2
|
+
/** Options for {@link hosted}. `backendURL` defaults to the build's. */
|
|
3
|
+
export type HostedOptions = Omit<HostedModeOptions, 'backendURL'> & {
|
|
4
|
+
/**
|
|
5
|
+
* Backend URL, relative (`/api/c15t`) or absolute. Defaults to the URL
|
|
6
|
+
* `consentManifest()` from `c15t/build` read from
|
|
7
|
+
* `VITE_C15T_BACKEND_URL` or `VITE_INTH_PROJECT_URL`.
|
|
8
|
+
*/
|
|
9
|
+
backendURL?: string;
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Build a hosted factory, taking the backend URL from the build when the
|
|
13
|
+
* options name none.
|
|
14
|
+
*
|
|
15
|
+
* @param options - The page's options.
|
|
16
|
+
* @param buildBackendURL - The backend URL the build read, if any.
|
|
17
|
+
* @returns A hosted transport factory.
|
|
18
|
+
* @throws {Error} When neither names a backend URL.
|
|
19
|
+
* @internal
|
|
20
|
+
*/
|
|
21
|
+
export declare const hostedWithBuild: (options: HostedOptions, buildBackendURL: string | undefined) => HostedModeFactory;
|
|
22
|
+
/**
|
|
23
|
+
* Ask the backend's `/init` for every visitor's policy.
|
|
24
|
+
*
|
|
25
|
+
* @param options - Backend URL, init headers and request overrides.
|
|
26
|
+
* @returns A transport factory for the provider's `mode`, carrying its
|
|
27
|
+
* options.
|
|
28
|
+
* @throws {Error} When no backend URL is passed and the build set none.
|
|
29
|
+
* @example
|
|
30
|
+
* ```tsx
|
|
31
|
+
* import { ConsentProvider, hosted } from 'c15t/react';
|
|
32
|
+
*
|
|
33
|
+
* <ConsentProvider options={{ mode: hosted() }}>{children}</ConsentProvider>;
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
export declare const hosted: (options?: HostedOptions) => HostedModeFactory;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { BrowserManifestModeFactory, BrowserManifestOptions } from '@c15t/core/transports/manifest-browser';
|
|
2
|
+
/**
|
|
3
|
+
* Manifest mode for the React provider: core's browser resolver, with the
|
|
4
|
+
* policy and backend URL the build integration downloaded as defaults.
|
|
5
|
+
*/
|
|
6
|
+
import type { ConsentManifest } from '@c15t/schema/types';
|
|
7
|
+
/** What a build integration downloaded, as `@c15t/core/generated` exports it. */
|
|
8
|
+
export interface BuildOutput {
|
|
9
|
+
backendURL?: string;
|
|
10
|
+
snapshot?: ConsentManifest;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Fill the options the page left out from the build: the backend URL that
|
|
14
|
+
* saves go to, and the snapshot unless the page passed one, a
|
|
15
|
+
* `manifestURL`, or `source: 'runtime'`.
|
|
16
|
+
*
|
|
17
|
+
* @param options - The page's options.
|
|
18
|
+
* @param build - What the build downloaded.
|
|
19
|
+
* @returns The options `manifest()` resolves with.
|
|
20
|
+
* @internal
|
|
21
|
+
*/
|
|
22
|
+
export declare const withBuildDefaults: (options: BrowserManifestOptions, build: BuildOutput) => BrowserManifestOptions;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve the policy in the browser from the backend's consent manifest.
|
|
25
|
+
*
|
|
26
|
+
* Without options it uses what `consentManifest()` from `c15t/build`
|
|
27
|
+
* downloaded: the snapshot and the backend URL from
|
|
28
|
+
* `VITE_C15T_BACKEND_URL` or `VITE_INTH_PROJECT_URL`, both served as
|
|
29
|
+
* `c15t/generated`. Without a
|
|
30
|
+
* snapshot, such as in dev after a failed fetch, it fetches
|
|
31
|
+
* `${backendURL}/manifest` at runtime. Saves go to the backend either way.
|
|
32
|
+
* With `manifestURL` or `source: 'runtime'`, also pass `source: 'runtime'`
|
|
33
|
+
* to `consentManifest()`, so the build downloads no snapshot.
|
|
34
|
+
*
|
|
35
|
+
* @param options - Overrides: your own `snapshot`, `source: 'runtime'`, a
|
|
36
|
+
* `manifestURL`, a `backendURL`, or the visitor's location as `inputs`.
|
|
37
|
+
* @returns A transport factory for the provider's `mode`, carrying its
|
|
38
|
+
* options.
|
|
39
|
+
* @throws {Error} When no snapshot, manifest URL or backend URL is known.
|
|
40
|
+
* @example
|
|
41
|
+
* ```tsx
|
|
42
|
+
* import { ConsentProvider, manifest } from 'c15t/react';
|
|
43
|
+
*
|
|
44
|
+
* <ConsentProvider options={{ mode: manifest() }}>{children}</ConsentProvider>;
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare const manifest: (options?: BrowserManifestOptions) => BrowserManifestModeFactory;
|
|
48
|
+
export type { BrowserManifestModeFactory, BrowserManifestOptions as ManifestModeOptions, } from '@c15t/core/transports/manifest-browser';
|
package/dist-types/version.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const version = "3.0.0
|
|
1
|
+
export declare const version = "3.0.0";
|
package/docs/README.md
CHANGED
|
@@ -6,7 +6,7 @@ These docs ship inside the package so coding agents can read them offline. Open
|
|
|
6
6
|
|
|
7
7
|
## Using these docs
|
|
8
8
|
|
|
9
|
-
These docs describe c15t v3. Find your app's row in Choose your setup, then follow that framework guide from start to finish; it names the files to create and the backend URL to use.
|
|
9
|
+
These docs describe c15t v3. Find your app's row in Choose your setup, then follow that framework guide from start to finish; it names the files to create and the backend URL to use. A visible banner does not prove anything: check that vendor requests wait for consent, that rejection survives a reload, and that preferences can be reopened.
|
|
10
10
|
|
|
11
11
|
## Start here
|
|
12
12
|
|
|
@@ -15,7 +15,7 @@ These docs describe c15t v3. Find your app's row in Choose your setup, then foll
|
|
|
15
15
|
- [How consent works](./concepts/how-consent-works.md): What c15t decides on each page load, the difference between a permission and a recorded choice, and what happens when a visitor saves.
|
|
16
16
|
- [Customize the interface](./customization/overview.md): Change c15t's consent banner and dialog one step at a time, from a prop to your own markup, and find where each step lives in your framework.
|
|
17
17
|
- [Verify consent](./guides/verify-consent.md): Check in a production build that vendor requests wait for consent, rejection survives a reload, preferences reopen and privacy signals apply.
|
|
18
|
-
- [
|
|
18
|
+
- [Upgrade a React app from v2](./frameworks/react/upgrade-v3.md): Upgrade a React app from c15t v2 (@c15t/react) to v3. Covers packages, ConsentProvider and transports, the useConsentManager codemod, callbacks, policies, styles, IAB and stored consent.
|
|
19
19
|
|
|
20
20
|
## More documentation
|
|
21
21
|
|
|
@@ -58,12 +58,13 @@ These docs describe c15t v3. Find your app's row in Choose your setup, then foll
|
|
|
58
58
|
- [Consent state reference](./concepts/consent-state.md): How c15t saves choices, gates IAB vendors, hydrates server records and keeps browser tabs and storage in step.
|
|
59
59
|
- [Data fetching](./concepts/data-fetching.md): Choose the recommended build-time policy snapshot or runtime manifest fetching, backend /init, browser resolution or offline rules, and understand where consent choices are saved.
|
|
60
60
|
- [How consent works](./concepts/how-consent-works.md): What c15t decides on each page load, the difference between a permission and a recorded choice, and what happens when a visitor saves.
|
|
61
|
+
- [Consent modes](./concepts/modes.md): Reference for manifest(), hosted() and offline() in every c15t framework package, where each one resolves the visitor's policy, what it adds to first-load JavaScript, the build-time manifest fetch and its failure policy, and the backend URL variable each framework reads.
|
|
61
62
|
- [Policies](./concepts/policies.md): How policy models, prompts and scope decide what c15t asks visitors, where to change the rules, and why a banner may not appear.
|
|
62
63
|
|
|
63
64
|
## Guides
|
|
64
65
|
|
|
65
66
|
- [Banner experiments](./guides/banner-experiments.md): Run A/B tests on consent banner presentation with any feature-flag provider or built-in weighted assignment, and attribute every impression and choice to its arm.
|
|
66
|
-
- [Troubleshooting](./guides/troubleshooting.md): Fix a missing banner, analytics that load before consent, choices lost on reload, CORS errors, hydration differences and failed static builds in c15t v3.
|
|
67
|
+
- [Troubleshooting](./guides/troubleshooting.md): Fix a missing banner, analytics that load before consent, choices lost on reload, CORS errors, hydration differences, failed manifest downloads, mode errors and failed static builds in c15t v3.
|
|
67
68
|
- [Verify consent](./guides/verify-consent.md): Check in a production build that vendor requests wait for consent, rejection survives a reload, preferences reopen and privacy signals apply.
|
|
68
69
|
|
|
69
70
|
## Customization
|
|
@@ -93,8 +94,8 @@ These docs describe c15t v3. Find your app's row in Choose your setup, then foll
|
|
|
93
94
|
- [Fathom Analytics](./integrations/fathom-analytics.md): Load Fathom Analytics only after measurement consent with the c15t fathomAnalytics helper, set its SPA mode, and check it in DevTools.
|
|
94
95
|
- [Front Chat](./integrations/front-chat.md): Load the Front Chat widget only after functionality consent with the c15t frontChat helper, forward CSP nonces, clear the session on revocation and check it in DevTools.
|
|
95
96
|
- [Google Maps](./integrations/google-maps.md): Gate a Google Maps iframe embed with c15t v3 so the map loads only after the visitor allows its consent category, in Next.js, TanStack Start, React, Nuxt, Vue, Astro, Svelte, SvelteKit, HTML or JavaScript.
|
|
96
|
-
- [Google Tag](./integrations/google-tag.md): Load gtag.js for Google Analytics or Google Ads with c15t Consent Mode v2 signals, and verify the consent commands in DevTools.
|
|
97
|
-
- [Google Tag Manager](./integrations/google-tag-manager.md): Load a Google Tag Manager container with c15t Consent Mode v2 signals, configure consent checks inside the container, and verify both in DevTools.
|
|
97
|
+
- [Google Tag](./integrations/google-tag.md): Load gtag.js for Google Analytics or Google Ads before or after consent with c15t Consent Mode v2 signals, and verify the consent commands in DevTools.
|
|
98
|
+
- [Google Tag Manager](./integrations/google-tag-manager.md): Load a Google Tag Manager container before or after consent with c15t Consent Mode v2 signals, configure consent checks inside the container, and verify both in DevTools.
|
|
98
99
|
- [Heap](./integrations/heap.md): Load the Heap config script and heap.js only after measurement consent with the c15t heap helper, and check it in DevTools.
|
|
99
100
|
- [Hightouch](./integrations/hightouch.md): Load the Hightouch Events browser SDK only after measurement consent with the c15t hightouch helper, and check page events in DevTools.
|
|
100
101
|
- [Hotjar](./integrations/hotjar.md): Load Hotjar only after measurement consent with the c15t hotjar helper, and check its loader and recordings in DevTools.
|
|
@@ -124,9 +125,6 @@ These docs describe c15t v3. Find your app's row in Choose your setup, then foll
|
|
|
124
125
|
- [TikTok Pixel](./integrations/tiktok-pixel.md): Load the TikTok Pixel only after marketing consent with the c15t tiktokPixel helper, guard ttq event calls, and check it in DevTools.
|
|
125
126
|
- [Umami Analytics](./integrations/umami-analytics.md): Load the Umami Analytics tracker only after measurement consent with the c15t umamiAnalytics helper, point it at a self-hosted instance, and check it in DevTools.
|
|
126
127
|
- [Vercel Analytics](./integrations/vercel-analytics.md): Load the Vercel Web Analytics script only after measurement consent with the c15t vercelAnalytics helper, choose the debug script, and check it in DevTools.
|
|
128
|
+
- [Vercel Speed Insights](./integrations/vercel-speed-insights.md): Load the Vercel Speed Insights collector only after measurement consent with the c15t vercelSpeedInsights helper, drop Web Vitals reports on revocation, and check it in DevTools.
|
|
127
129
|
- [X Pixel](./integrations/x-pixel.md): Load the X Pixel only after marketing consent with the c15t xPixel helper, guard twq conversion events, and check it in DevTools.
|
|
128
130
|
- [YouTube](./integrations/youtube.md): Gate YouTube embeds with c15t v3 in Next.js, TanStack Start, React, Nuxt, Vue, Astro, Svelte, SvelteKit or JavaScript.
|
|
129
|
-
|
|
130
|
-
## Reference
|
|
131
|
-
|
|
132
|
-
- [Migrate to v3](./upgrade-v3.md): Upgrade from c15t v2 to v3. Pick the guide for the v2 package you use (@c15t/nextjs, @c15t/react or the c15t store), rename @c15t/scripts, keep visitors' choices, and upgrade a self-hosted backend and the Node.js SDK.
|
|
@@ -76,10 +76,15 @@ public policy manifest, never a response that contains a visitor's consent.
|
|
|
76
76
|
## How the server gets the policy
|
|
77
77
|
|
|
78
78
|
Use a build-time manifest as the default for supported production builds.
|
|
79
|
-
Next.js, TanStack Start, Nuxt
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
`manifest()` is the default mode in Next.js, TanStack Start, Nuxt, Astro and
|
|
80
|
+
SvelteKit, so their servers resolve requests from the deployment's snapshot.
|
|
81
|
+
React, Vue and Svelte single-page apps have no server, so their quickstarts
|
|
82
|
+
use `hosted()`: the backend reads each visitor's location from the `/init`
|
|
83
|
+
request. They can bundle the manifest for browser resolution too, but a
|
|
84
|
+
regional policy still needs `/init` on a first visit unless the page knows
|
|
85
|
+
the location. The framework quickstarts show the build
|
|
86
|
+
integration. [Consent modes](./modes.md) lists every mode, its
|
|
87
|
+
options and the backend URL variable each framework reads.
|
|
83
88
|
|
|
84
89
|
The build fetches your public policy once and bundles it, so the server never
|
|
85
90
|
fetches it at runtime.
|
|
@@ -88,19 +93,49 @@ The snapshot is fixed at build time:
|
|
|
88
93
|
|
|
89
94
|
* Rebuild after changing policies, translations or vendors. If your CI caches
|
|
90
95
|
build output, force a fresh build.
|
|
91
|
-
* The build must reach the backend. A failed fetch stops Next.js, TanStack
|
|
92
|
-
Start, SvelteKit and Vite builds. By default, Astro and Nuxt log a warning
|
|
93
|
-
instead and fetch the policy at runtime.
|
|
94
96
|
* Consent choices still go to the backend.
|
|
95
97
|
|
|
98
|
+
The build reads the backend URL from your public backend URL variable when
|
|
99
|
+
the config doesn't pass one: `NEXT_PUBLIC_C15T_BACKEND_URL` in Next.js,
|
|
100
|
+
`NUXT_PUBLIC_C15T_BACKEND_URL` in Nuxt, `PUBLIC_C15T_BACKEND_URL` in Astro,
|
|
101
|
+
Svelte and SvelteKit, and `VITE_C15T_BACKEND_URL` in TanStack Start and other
|
|
102
|
+
Vite apps. Each also reads the matching Inth variable, such as
|
|
103
|
+
`NEXT_PUBLIC_INTH_PROJECT_URL`, when the c15t one is unset. See
|
|
104
|
+
[set the backend URL](./modes.md#set-the-backend-url).
|
|
105
|
+
|
|
106
|
+
The fetch waits at most 10 seconds. When it fails, or no backend URL is set,
|
|
107
|
+
every framework does the same thing:
|
|
108
|
+
|
|
109
|
+
| Command | Default when the fetch fails |
|
|
110
|
+
| ------------------------------------------------------------------------- | -------------------------------------------------------- |
|
|
111
|
+
| Production build: `next build`, `vite build`, `nuxt build`, `astro build` | The build stops with an error. |
|
|
112
|
+
| Dev: `next dev`, `vite dev`, `nuxt dev`, `astro dev` | A warning, and the server fetches the policy at runtime. |
|
|
113
|
+
|
|
114
|
+
Set `onBuildError` to use one behaviour for both. `'fail'` stops dev too.
|
|
115
|
+
`'runtime'` lets a production build finish, and the server fetches the policy
|
|
116
|
+
at runtime. The `C15T_ON_BUILD_ERROR` environment variable overrides the
|
|
117
|
+
option, so you can deploy during a backend outage without a code change:
|
|
118
|
+
|
|
119
|
+
```sh
|
|
120
|
+
C15T_ON_BUILD_ERROR=runtime npm run build
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Turborepo's strict environment mode hides undeclared variables from tasks, so
|
|
124
|
+
list `C15T_ON_BUILD_ERROR` in the build task's `passThroughEnv` there.
|
|
125
|
+
|
|
126
|
+
The build skips the fetch, without an error, when it can't use a snapshot,
|
|
127
|
+
for example when the backend URL is relative. With `onBuildError: 'fail'`, a
|
|
128
|
+
relative URL stops the build. [Consent modes](./modes.md#what-happens-when-the-download-fails)
|
|
129
|
+
lists every case.
|
|
130
|
+
|
|
96
131
|
For deployments that need policy updates without a rebuild, choose a runtime
|
|
97
132
|
path:
|
|
98
133
|
|
|
99
|
-
* **Cached manifest
|
|
134
|
+
* **Cached manifest**, `manifest({ source: 'runtime' })`.
|
|
100
135
|
Your server downloads the project's public policy file, caches it, and
|
|
101
136
|
resolves each visitor locally. Consent saves still go to the backend.
|
|
102
|
-
* **`/init
|
|
103
|
-
every page load makes a request to the backend.
|
|
137
|
+
* **`/init`**, `hosted()`. Each visit asks the backend to resolve the visitor.
|
|
138
|
+
Simpler, but every page load makes a request to the backend.
|
|
104
139
|
|
|
105
140
|
[Data fetching](./data-fetching.md) compares them in detail,
|
|
106
141
|
including proxies and custom transports.
|
|
@@ -81,4 +81,4 @@ client render. Set
|
|
|
81
81
|
|
|
82
82
|
Use effective permissions to gate work and explicit choices to inspect what the
|
|
83
83
|
visitor confirmed. Read [how consent works](./how-consent-works.md#a-permission-is-not-a-recorded-choice) for that
|
|
84
|
-
distinction and [
|
|
84
|
+
distinction and [policies](./policies.md) for v3 policy configuration.
|
|
@@ -130,8 +130,11 @@ Forward that configuration intact. Copying an allowed category into a receipt
|
|
|
130
130
|
would invent a grant and lose its original confirmation time.
|
|
131
131
|
|
|
132
132
|
Valid v2 records can be read without a startup rewrite. The next explicit action
|
|
133
|
-
writes the v3 format.
|
|
134
|
-
|
|
133
|
+
writes the v3 format. The upgrade guides for
|
|
134
|
+
[Next.js](https://c15t.com/docs/frameworks/next/upgrade-v3#keep-visitors-existing-choices),
|
|
135
|
+
[React](../frameworks/react/upgrade-v3.md#keep-visitors-existing-choices) and
|
|
136
|
+
[JavaScript](https://c15t.com/docs/frameworks/javascript/upgrade-v3#keep-visitors-existing-choices)
|
|
137
|
+
cover how v3 treats v2 records.
|
|
135
138
|
|
|
136
139
|
## Keep open tabs in step
|
|
137
140
|
|