@c15t/react 3.0.0-alpha.1 → 3.0.0-alpha.10
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 +96 -70
- package/README.md +21 -17
- package/SKILL.md +34 -0
- package/dist/aggregate-components.js +1 -1
- package/dist/chunk-warming.js +1 -1
- package/dist/component-hooks/use-headless-consent-ui.js +1 -1
- package/dist/component-hooks/use-headless-iab-consent-ui.js +1 -1
- package/dist/component-hooks/use-panel-trigger.js +1 -1
- package/dist/components/consent-gate/atoms.js +1 -0
- package/dist/components/consent-gate/consent-gate.js +2 -0
- package/dist/components/consent-gate/frame.js +2 -0
- package/dist/components/consent-gate/index.js +2 -0
- package/dist/components/consent-preferences-link/consent-preferences-link.js +1 -1
- package/dist/components/iab-panel/atoms/card.js +1 -1
- package/dist/components/iab-panel/atoms/feature-item.js +2 -0
- package/dist/components/iab-panel/atoms/header.js +1 -1
- package/dist/components/iab-panel/atoms/purpose-item.js +1 -1
- package/dist/components/iab-panel/atoms/root.js +1 -1
- package/dist/components/iab-panel/atoms/stack-item.js +1 -1
- package/dist/components/iab-panel/atoms/vendor-list.js +1 -1
- package/dist/components/iab-panel/hooks/use-gvl-data.js +1 -1
- package/dist/components/iab-panel/iab-panel.js +1 -1
- package/dist/components/iab-panel/index.js +1 -1
- package/dist/components/iab-prompt/atoms/overlay.js +1 -1
- package/dist/components/iab-prompt/atoms/root.js +1 -1
- package/dist/components/panel/atoms/card.js +1 -1
- package/dist/components/panel/atoms/overlay.js +1 -1
- package/dist/components/panel/atoms/root.js +1 -1
- package/dist/components/panel/panel.js +1 -1
- package/dist/components/panel-trigger/atoms/button.js +1 -1
- package/dist/components/panel-trigger/atoms/icon.js +1 -1
- package/dist/components/panel-trigger/atoms/root.js +1 -1
- package/dist/components/panel-trigger/atoms/toolbar.js +1 -1
- package/dist/components/panel-trigger/atoms/trigger-icons.js +1 -0
- package/dist/components/panel-trigger/panel-trigger-toolbar.js +1 -1
- package/dist/components/panel-trigger/panel-trigger.js +1 -1
- package/dist/components/preferences/atoms/accordion.js +1 -1
- package/dist/components/preferences/atoms/root.js +1 -1
- package/dist/components/preferences/atoms/vendor-list.js +1 -0
- package/dist/components/preferences/index.js +1 -1
- package/dist/components/prompt/atoms/early-tap-script.js +2 -0
- package/dist/components/prompt/atoms/overlay.js +1 -1
- package/dist/components/prompt/atoms/root.js +1 -1
- package/dist/components/prompt/components.js +1 -1
- package/dist/components/prompt/policy-actions.js +1 -1
- package/dist/components/prompt/prompt.js +1 -1
- package/dist/components/shared/dialog-sheets.js +1 -0
- package/dist/components/shared/first-paint-sheets.js +1 -0
- package/dist/components/shared/iab-dialog-sheets.js +1 -0
- package/dist/components/shared/iab-first-paint-sheets.js +1 -0
- package/dist/components/shared/libs/compose-refs.js +1 -0
- package/dist/components/shared/libs/slot.js +1 -1
- package/dist/components/shared/primitives/button.js +1 -1
- package/dist/components/shared/primitives/legal-links/index.js +1 -1
- package/dist/components/shared/streamed-surface.js +2 -0
- package/dist/components/shared/surface-styles.js +2 -0
- package/dist/components/shared/ui/dialog/dialog.js +1 -1
- package/dist/components/shared/ui/icon.js +1 -1
- package/dist/components/shared/ui/logo.js +1 -1
- package/dist/components/shared/ui/preference-item/preference-item.js +1 -1
- package/dist/consent-gate.js +2 -0
- package/dist/consent-theme.js +1 -0
- package/dist/context/consent-tracking-context.js +1 -1
- package/dist/context/index.js +1 -1
- package/dist/context.js +1 -1
- package/dist/devtools-launcher.js +2 -0
- package/dist/devtools.js +1 -1
- package/dist/draft-context.js +2 -0
- package/dist/draft.js +1 -1
- package/dist/external-iab-context.js +1 -1
- package/dist/gpp.js +2 -0
- package/dist/headless.js +1 -1
- package/dist/hooks/use-color-scheme.js +1 -1
- package/dist/hooks/use-committed-ref.js +2 -0
- package/dist/hooks/use-focus-trap.js +1 -1
- package/dist/hooks/use-headless-iab-consent-ui.js +1 -1
- package/dist/hooks/use-iab-policy-guard.js +1 -0
- package/dist/hooks/use-late-entry.js +2 -0
- package/dist/hooks.js +1 -1
- package/dist/iab/styles.tw3.css +5 -45
- package/dist/iab-context.js +1 -1
- package/dist/index-parts/consent-banner.js +1 -0
- package/dist/index-parts/consent-dialog-link.js +1 -0
- package/dist/index-parts/consent-dialog-trigger.js +1 -0
- package/dist/index-parts/consent-dialog.js +1 -0
- package/dist/index-parts/consent-gate.js +1 -0
- package/dist/index-parts/core.js +1 -0
- package/dist/index-parts/draft.js +1 -0
- package/dist/index-parts/frame.js +1 -0
- package/dist/index-parts/hooks.js +1 -0
- package/dist/index-parts/hosted.js +1 -0
- package/dist/index-parts/module-hooks.js +1 -0
- package/dist/index-parts/offline.js +1 -0
- package/dist/index-parts/presets.js +1 -0
- package/dist/index-parts/provider.js +1 -0
- package/dist/index-parts/theme.js +1 -0
- package/dist/index-parts/translations.js +1 -0
- package/dist/index.js +1 -1
- package/dist/kernel-selector.js +1 -0
- package/dist/modes.js +1 -0
- package/dist/module-hooks/iframe-blocker.js +1 -1
- package/dist/module-hooks/network-blocker.js +1 -1
- package/dist/module-hooks/network-hold.js +2 -0
- package/dist/module-hooks/persistence.js +1 -1
- package/dist/panel-link.js +1 -1
- package/dist/panel-trigger.js +1 -1
- package/dist/panel.js +1 -1
- package/dist/postcss-tailwind3.js +1 -0
- package/dist/preferences.js +1 -2
- package/dist/provider.js +1 -1
- package/dist/server/fetch-ssr-data.js +1 -1
- package/dist/server/headers.js +1 -1
- package/dist/server/normalize-url.js +1 -1
- package/dist/styles.tw3.css +33 -51
- package/dist/transports/hosted.js +1 -0
- package/dist/transports/manifest.js +1 -0
- package/dist/transports/offline.js +1 -1
- package/dist/utils/deferred-module.js +2 -0
- package/dist/utils/merge-slot-props.js +1 -1
- package/dist/utils/theme-utils.js +1 -1
- package/dist/version.js +1 -1
- package/dist-types/aggregate-components.d.ts +2 -2
- package/dist-types/chunk-warming.d.ts +45 -8
- package/dist-types/component-hooks/use-headless-consent-ui.d.ts +5 -5
- package/dist-types/component-hooks/use-headless-iab-consent-ui.d.ts +2 -2
- package/dist-types/components/consent-gate/atoms.d.ts +11 -0
- package/dist-types/components/consent-gate/consent-gate.d.ts +2 -0
- package/dist-types/components/consent-gate/frame.d.ts +19 -0
- package/dist-types/components/consent-gate/index.d.ts +25 -0
- package/dist-types/components/{frame → consent-gate}/types.d.ts +7 -7
- package/dist-types/components/consent-preferences-link/consent-preferences-link.d.ts +1 -1
- package/dist-types/components/consent-preferences-link/index.d.ts +1 -1
- package/dist-types/components/iab-panel/atoms/feature-item.d.ts +28 -0
- package/dist-types/components/iab-panel/atoms/purpose-item.d.ts +5 -2
- package/dist-types/components/iab-panel/atoms/stack-item.d.ts +7 -2
- package/dist-types/components/iab-panel/atoms/vendor-list.d.ts +1 -1
- package/dist-types/components/iab-panel/iab-panel.d.ts +3 -3
- package/dist-types/components/iab-panel/index.d.ts +29 -26
- package/dist-types/components/iab-panel/use-iab-translations.d.ts +4 -0
- package/dist-types/components/iab-prompt/iab-prompt.d.ts +3 -3
- package/dist-types/components/iab-prompt/index.d.ts +19 -19
- package/dist-types/components/panel/atoms/card.d.ts +5 -4
- package/dist-types/components/panel/atoms/overlay.d.ts +1 -1
- package/dist-types/components/panel/index.d.ts +8 -8
- package/dist-types/components/panel/panel.d.ts +3 -3
- package/dist-types/components/panel-link/index.d.ts +1 -1
- package/dist-types/components/panel-trigger/atoms/button.d.ts +1 -1
- package/dist-types/components/panel-trigger/atoms/icon.d.ts +1 -1
- package/dist-types/components/panel-trigger/atoms/root.d.ts +2 -2
- package/dist-types/components/panel-trigger/atoms/toolbar.d.ts +2 -2
- package/dist-types/components/panel-trigger/atoms/trigger-icons.d.ts +25 -0
- package/dist-types/components/panel-trigger/index.d.ts +4 -4
- package/dist-types/components/panel-trigger/panel-trigger-toolbar.d.ts +1 -1
- package/dist-types/components/panel-trigger/panel-trigger.d.ts +9 -17
- package/dist-types/components/panel-trigger/types.d.ts +1 -1
- package/dist-types/components/preferences/atoms/accordion.d.ts +6 -4
- package/dist-types/components/preferences/atoms/button.d.ts +1 -1
- package/dist-types/components/preferences/atoms/footer.d.ts +1 -1
- package/dist-types/components/preferences/atoms/root.d.ts +1 -1
- package/dist-types/components/preferences/atoms/vendor-list.d.ts +23 -0
- package/dist-types/components/preferences/index.d.ts +14 -12
- package/dist-types/components/preferences/policy-actions.d.ts +2 -2
- package/dist-types/components/preferences/preferences.d.ts +1 -1
- package/dist-types/components/preferences/types.d.ts +1 -1
- package/dist-types/components/prompt/atoms/early-tap-script.d.ts +17 -0
- package/dist-types/components/prompt/atoms/root.d.ts +4 -0
- package/dist-types/components/prompt/components.d.ts +9 -3
- package/dist-types/components/prompt/index.d.ts +12 -12
- package/dist-types/components/prompt/policy-actions.d.ts +2 -2
- package/dist-types/components/prompt/prompt.d.ts +5 -1
- package/dist-types/components/shared/dialog-sheets.d.ts +9 -0
- package/dist-types/components/shared/first-paint-sheets.d.ts +8 -0
- package/dist-types/components/shared/iab-dialog-sheets.d.ts +3 -0
- package/dist-types/components/shared/iab-first-paint-sheets.d.ts +3 -0
- package/dist-types/components/shared/libs/compose-refs.d.ts +20 -0
- package/dist-types/components/shared/policy-actions.d.ts +2 -2
- package/dist-types/components/shared/primitives/box.d.ts +1 -1
- package/dist-types/components/shared/primitives/button.d.ts +2 -2
- package/dist-types/components/shared/primitives/button.types.d.ts +1 -1
- package/dist-types/components/shared/streamed-surface.d.ts +23 -0
- package/dist-types/components/shared/surface-styles.d.ts +36 -0
- package/dist-types/components/shared/ui/accordion/accordion.d.ts +2 -2
- package/dist-types/components/shared/ui/accordion/index.d.ts +2 -2
- package/dist-types/components/shared/ui/animated-collapse/index.d.ts +2 -2
- package/dist-types/components/shared/ui/branding.d.ts +1 -1
- package/dist-types/components/shared/ui/button/button.d.ts +1 -1
- package/dist-types/components/shared/ui/button/index.d.ts +2 -2
- package/dist-types/components/shared/ui/collapsible/index.d.ts +1 -1
- package/dist-types/components/shared/ui/dialog/index.d.ts +1 -1
- package/dist-types/components/shared/ui/icon.d.ts +2 -1
- package/dist-types/components/shared/ui/logo.d.ts +0 -10
- package/dist-types/components/shared/ui/preference-item/index.d.ts +1 -1
- package/dist-types/components/shared/ui/preference-item/preference-item.d.ts +13 -0
- package/dist-types/components/shared/ui/switch/index.d.ts +2 -2
- package/dist-types/components/shared/ui/switch/switch.d.ts +1 -1
- package/dist-types/components/shared/ui/tabs/index.d.ts +1 -1
- package/dist-types/consent-gate.d.ts +1 -0
- package/dist-types/consent-theme.d.ts +38 -0
- package/dist-types/context/consent-tracking-context.d.ts +10 -0
- package/dist-types/context/index.d.ts +3 -3
- package/dist-types/context/theme-context.d.ts +3 -3
- package/dist-types/context.d.ts +25 -1
- package/dist-types/devtools-launcher.d.ts +29 -0
- package/dist-types/devtools.d.ts +13 -2
- package/dist-types/draft-context.d.ts +31 -0
- package/dist-types/draft.d.ts +81 -9
- package/dist-types/gpp.d.ts +27 -0
- package/dist-types/headless.d.ts +6 -7
- package/dist-types/hooks/use-committed-ref.d.ts +24 -0
- package/dist-types/hooks/use-focus-trap.d.ts +3 -1
- package/dist-types/hooks/use-headless-iab-consent-ui.d.ts +1 -1
- package/dist-types/hooks/use-iab-manager.d.ts +5 -5
- package/dist-types/hooks/use-iab-policy-guard.d.ts +35 -0
- package/dist-types/hooks/use-late-entry.d.ts +14 -0
- package/dist-types/hooks/use-theme.d.ts +1 -1
- package/dist-types/hooks.d.ts +106 -11
- package/dist-types/iab.d.ts +7 -7
- package/dist-types/index-parts/consent-banner.d.ts +7 -0
- package/dist-types/index-parts/consent-dialog-link.d.ts +7 -0
- package/dist-types/index-parts/consent-dialog-trigger.d.ts +7 -0
- package/dist-types/index-parts/consent-dialog.d.ts +7 -0
- package/dist-types/index-parts/consent-gate.d.ts +7 -0
- package/dist-types/index-parts/core.d.ts +7 -0
- package/dist-types/index-parts/draft.d.ts +7 -0
- package/dist-types/index-parts/frame.d.ts +7 -0
- package/dist-types/index-parts/hooks.d.ts +7 -0
- package/dist-types/index-parts/hosted.d.ts +7 -0
- package/dist-types/index-parts/module-hooks.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-parts/provider.d.ts +7 -0
- package/dist-types/index-parts/theme.d.ts +8 -0
- package/dist-types/index-parts/translations.d.ts +7 -0
- package/dist-types/index.d.ts +32 -28
- package/dist-types/kernel-selector.d.ts +68 -0
- package/dist-types/modes.d.ts +26 -0
- package/dist-types/module-hooks/iframe-blocker.d.ts +33 -1
- package/dist-types/module-hooks/network-blocker.d.ts +23 -0
- package/dist-types/module-hooks/network-hold.d.ts +47 -0
- package/dist-types/module-hooks.d.ts +4 -4
- package/dist-types/panel-link.d.ts +1 -1
- package/dist-types/panel-trigger.d.ts +1 -1
- package/dist-types/panel.d.ts +13 -1
- package/dist-types/postcss-tailwind3.d.ts +21 -0
- package/dist-types/preferences.d.ts +12 -1
- package/dist-types/primitives/accordion.d.ts +1 -1
- package/dist-types/primitives/button.d.ts +1 -1
- package/dist-types/primitives/collapsible.d.ts +1 -1
- package/dist-types/primitives/dialog.d.ts +1 -1
- package/dist-types/primitives/preference-item.d.ts +1 -1
- package/dist-types/primitives/switch.d.ts +1 -1
- package/dist-types/primitives/tabs.d.ts +1 -1
- package/dist-types/primitives.d.ts +7 -7
- package/dist-types/prompt.d.ts +1 -1
- package/dist-types/provider.d.ts +169 -28
- package/dist-types/server/fetch-ssr-data.d.ts +1 -1
- package/dist-types/server/headers.d.ts +14 -4
- package/dist-types/server/index.d.ts +5 -5
- package/dist-types/server/normalize-url.d.ts +14 -7
- package/dist-types/server/types.d.ts +12 -1
- package/dist-types/theme-provider.d.ts +2 -2
- package/dist-types/transports/hosted.d.ts +36 -0
- package/dist-types/transports/manifest.d.ts +48 -0
- package/dist-types/transports/offline.d.ts +7 -16
- package/dist-types/types/index.d.ts +3 -3
- package/dist-types/types/manager.d.ts +1 -1
- package/dist-types/types/theme/index.d.ts +1 -1
- package/dist-types/ui-config-context.d.ts +14 -2
- package/dist-types/utils/deferred-module.d.ts +13 -0
- package/dist-types/utils/index.d.ts +4 -4
- package/dist-types/utils/merge-slot-props.d.ts +17 -3
- package/dist-types/utils/merge-styles.d.ts +1 -1
- package/dist-types/utils/theme-utils.d.ts +18 -3
- package/dist-types/version.d.ts +1 -1
- package/docs/README.md +96 -70
- package/docs/assets/v3/bottom-bar.png +0 -0
- package/docs/assets/v3/brand-card.png +0 -0
- package/docs/assets/v3/brand-preferences.png +0 -0
- package/docs/assets/v3/choice-wall.png +0 -0
- package/docs/assets/v3/headless-bar-html.png +0 -0
- package/docs/assets/v3/headless-bar-mobile.png +0 -0
- package/docs/assets/v3/headless-bar.png +0 -0
- package/docs/assets/v3/slim-bar.png +0 -0
- package/docs/concepts/choose-your-setup.md +138 -0
- package/docs/concepts/consent-categories.md +84 -0
- package/docs/concepts/consent-state.md +421 -0
- package/docs/concepts/data-fetching.md +270 -0
- package/docs/concepts/how-consent-works.md +123 -0
- package/docs/concepts/modes.md +278 -0
- package/docs/{frameworks/react/concepts/policy-presets.md → concepts/policies.md} +8 -60
- package/docs/customization/class-names.md +202 -0
- package/docs/customization/dark-mode.md +157 -0
- package/docs/customization/motion.md +128 -0
- package/docs/customization/overview.md +68 -33
- package/docs/customization/recipes.md +838 -47
- package/docs/customization/slots.md +217 -35
- package/docs/customization/stylesheets.md +248 -0
- package/docs/customization/tailwind.md +863 -0
- package/docs/customization/tokens.md +167 -36
- package/docs/customization/translations.md +87 -3
- package/docs/frameworks/react/callbacks.md +118 -0
- package/docs/frameworks/react/clear-on-revocation.md +106 -0
- package/docs/frameworks/react/components/consent-banner.md +48 -27
- package/docs/frameworks/react/components/consent-dialog-link.md +13 -11
- package/docs/frameworks/react/components/consent-dialog-trigger.md +86 -76
- package/docs/frameworks/react/components/consent-dialog.md +111 -58
- package/docs/frameworks/react/components/{frame.md → consent-gate.md} +70 -49
- package/docs/frameworks/react/components/consent-provider.md +140 -0
- package/docs/frameworks/react/components/consent-widget.md +69 -24
- package/docs/frameworks/react/components/dev-tools.md +76 -85
- package/docs/frameworks/react/components.md +113 -0
- package/docs/frameworks/react/compose.md +354 -0
- package/docs/frameworks/react/content-security-policy.md +143 -0
- package/docs/frameworks/react/customize.md +258 -0
- package/docs/frameworks/react/embeds.md +89 -0
- package/docs/frameworks/react/gpp.md +163 -0
- package/docs/frameworks/react/headless.md +4 -4
- package/docs/frameworks/react/hooks.md +70 -0
- package/docs/frameworks/react/iab.md +259 -0
- package/docs/frameworks/react/network-blocker.md +140 -0
- package/docs/frameworks/react/quickstart.md +220 -102
- package/docs/frameworks/react/rendering.md +263 -0
- package/docs/frameworks/react/scripts.md +114 -0
- package/docs/frameworks/react/translations.md +155 -0
- package/docs/frameworks/react/troubleshooting.md +188 -61
- package/docs/frameworks/react/upgrade-v3.md +651 -0
- package/docs/frameworks/react/vendor-consent.md +188 -0
- package/docs/guides/banner-experiments.md +672 -0
- package/docs/guides/troubleshooting.md +192 -54
- package/docs/guides/verify-consent.md +96 -49
- package/docs/integrations/adobe-analytics.md +177 -183
- package/docs/integrations/ahrefs-analytics.md +162 -178
- package/docs/integrations/amplitude.md +172 -180
- package/docs/integrations/building-integrations.md +137 -33
- package/docs/integrations/clearbit.md +164 -178
- package/docs/integrations/cloudflare-web-analytics.md +166 -180
- package/docs/integrations/cloudflare-zaraz.md +333 -0
- package/docs/integrations/crisp.md +174 -182
- package/docs/integrations/databuddy.md +167 -197
- package/docs/integrations/fathom-analytics.md +168 -180
- package/docs/integrations/front-chat.md +308 -0
- package/docs/integrations/google-maps.md +142 -108
- package/docs/integrations/google-tag-manager.md +258 -185
- package/docs/integrations/google-tag.md +226 -182
- package/docs/integrations/heap.md +173 -179
- package/docs/integrations/hightouch.md +171 -181
- package/docs/integrations/hotjar.md +169 -179
- package/docs/integrations/intercom.md +193 -177
- package/docs/integrations/klaviyo.md +473 -0
- package/docs/integrations/linkedin-insights.md +184 -174
- package/docs/integrations/logrocket.md +170 -180
- package/docs/integrations/matomo-analytics.md +198 -202
- package/docs/integrations/meta-pixel.md +198 -174
- package/docs/integrations/microsoft-clarity.md +173 -179
- package/docs/integrations/microsoft-uet.md +158 -178
- package/docs/integrations/mixpanel-analytics.md +165 -184
- package/docs/integrations/one-dollar-stats.md +292 -0
- package/docs/integrations/openai-pixel.md +214 -325
- package/docs/integrations/overview.md +152 -83
- package/docs/integrations/pinterest-tag.md +315 -0
- package/docs/integrations/pirsch.md +179 -183
- package/docs/integrations/plausible-analytics.md +182 -182
- package/docs/integrations/posthog.md +323 -264
- package/docs/integrations/promptwatch.md +164 -178
- package/docs/integrations/reddit-pixel.md +195 -181
- package/docs/integrations/rudderstack.md +211 -210
- package/docs/integrations/rybbit-analytics.md +181 -184
- package/docs/integrations/segment.md +192 -178
- package/docs/integrations/sentry.md +402 -0
- package/docs/integrations/snapchat-pixel.md +196 -180
- package/docs/integrations/tiktok-pixel.md +181 -174
- package/docs/integrations/umami-analytics.md +173 -182
- package/docs/integrations/vercel-analytics.md +176 -181
- package/docs/integrations/x-pixel.md +186 -174
- package/docs/integrations/youtube.md +150 -111
- package/package.json +48 -17
- package/dist/component-hooks/use-manager.js +0 -2
- package/dist/components/frame/atoms.js +0 -1
- package/dist/components/frame/frame.js +0 -2
- package/dist/components/frame/index.js +0 -2
- package/dist/frame.js +0 -2
- package/dist/ui-save.js +0 -1
- package/dist-types/component-hooks/use-manager.d.ts +0 -40
- package/dist-types/components/frame/atoms.d.ts +0 -11
- package/dist-types/components/frame/frame.d.ts +0 -2
- package/dist-types/components/frame/index.d.ts +0 -24
- package/dist-types/frame.d.ts +0 -1
- package/dist-types/ui-save.d.ts +0 -5
- package/docs/assets/v3/brand-bar.png +0 -0
- package/docs/assets/v3/mobile-card.png +0 -0
- package/docs/assets/v3/preferences.png +0 -0
- package/docs/frameworks/react/components/consent-manager-provider.md +0 -71
- package/docs/frameworks/react/concepts/consent-categories.md +0 -33
- package/docs/frameworks/react/hooks/use-consent-manager/overview.md +0 -58
- package/docs/frameworks/react/iab/overview.md +0 -53
- package/docs/frameworks/react/script-loader.md +0 -63
- package/docs/frameworks/react/styling/overview.md +0 -217
- package/docs/guides/consent-state.md +0 -60
- package/docs/guides/data-fetching.md +0 -163
- package/docs/guides/deployment-modes.md +0 -63
- package/docs/integrations/clear-on-revocation.md +0 -167
- package/docs/upgrade-v3.md +0 -334
- package/readme.json +0 -48
- package/src/iab/styles.css +0 -11
- package/src/styles.css +0 -10
- /package/dist/components/{frame → consent-gate}/types.js +0 -0
|
@@ -1,212 +1,153 @@
|
|
|
1
1
|
---
|
|
2
2
|
title: Google Tag
|
|
3
|
-
description:
|
|
4
|
-
|
|
3
|
+
description: Load gtag.js for Google Analytics or Google Ads before or after
|
|
4
|
+
consent with c15t Consent Mode v2 signals, and verify the consent commands in
|
|
5
|
+
DevTools.
|
|
6
|
+
icon: google-analytics
|
|
5
7
|
group: integrations
|
|
6
8
|
---
|
|
7
9
|
|
|
8
|
-
##
|
|
10
|
+
## Configure the Google tag
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
|
15
|
-
|
|
|
12
|
+
Copy the tag ID, for example `G-XXXXXXXXXX` for Google Analytics or
|
|
13
|
+
`AW-XXXXXXXXX` for Google Ads. Remove any `gtag.js` snippet already in your
|
|
14
|
+
HTML and any tag-manager entry that loads the same tag.
|
|
15
|
+
|
|
16
|
+
| Package manager | Command |
|
|
17
|
+
| :-------------- | :------------------------------------- |
|
|
18
|
+
| npm | `npm install @c15t/integrations@alpha` |
|
|
19
|
+
| pnpm | `pnpm add @c15t/integrations@alpha` |
|
|
20
|
+
| yarn | `yarn add @c15t/integrations@alpha` |
|
|
21
|
+
| bun | `bun add @c15t/integrations@alpha` |
|
|
16
22
|
|
|
17
23
|
```ts title="src/consent-scripts.ts"
|
|
18
|
-
import { gtag } from '@c15t/
|
|
24
|
+
import { gtag } from '@c15t/integrations/google-tag';
|
|
19
25
|
|
|
20
26
|
export const scripts = [gtag({ id: 'G-XXXXXXXXXX', category: 'measurement' })];
|
|
21
27
|
```
|
|
22
28
|
|
|
23
|
-
Use your Google tag ID and pass `scripts` to the existing provider options.
|
|
24
|
-
Choose `marketing` for a configuration whose purpose is advertising. The
|
|
25
|
-
category describes the integration but does not override `alwaysLoad`.
|
|
26
|
-
Remove a separately installed `gtag.js` snippet or a duplicate tag-manager
|
|
27
|
-
configuration before testing.
|
|
28
|
-
|
|
29
29
|
## Register the scripts
|
|
30
30
|
|
|
31
|
-
Complete your [framework quickstart](https://c15t.com/docs/frameworks) first. Keep its Inth
|
|
31
|
+
Complete your [framework quickstart](https://v3.c15t.com/docs/frameworks) first. Keep its Inth
|
|
32
32
|
endpoint, policy, styles and consent UI. Remove the vendor's original script,
|
|
33
|
-
SDK initializer or tag-manager entry so
|
|
33
|
+
SDK initializer or tag-manager entry, so the vendor loads only through c15t.
|
|
34
34
|
|
|
35
|
-
The
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
The vendor pages put the helper in `src/consent-scripts.ts`. If your framework
|
|
36
|
+
quickstart already has a `scripts` array, such as the one in `c15t.config.ts`
|
|
37
|
+
in the Next.js guide, add the helper to that array instead of creating a
|
|
38
|
+
second file.
|
|
39
|
+
The `scripts` export is a configuration, not an initializer. Add it to the c15t provider you already have, at the registration
|
|
40
|
+
point for your framework below. These are edits to that provider, not a second
|
|
41
|
+
provider.
|
|
38
42
|
|
|
39
43
|
**Next.js**
|
|
40
44
|
|
|
41
|
-
|
|
45
|
+
Add the configuration to `scripts` in `c15t.config.ts`, next to
|
|
46
|
+
`next.config.ts`:
|
|
42
47
|
|
|
43
|
-
```ts
|
|
44
|
-
import {
|
|
45
|
-
import { scripts } from './consent-scripts';
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
Keep the server-resolved `state` and shared `consentConfig` from your
|
|
49
|
-
router guide. Its manifest, init and save URLs stay in effect. Add
|
|
50
|
-
`scripts` as a top-level prop on the existing root:
|
|
48
|
+
```ts title="c15t.config.ts"
|
|
49
|
+
import { defineConsentConfig } from 'c15t/next';
|
|
50
|
+
import { scripts } from './src/consent-scripts';
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
<ConsentRoot state={state} config={consentConfig} scripts={scripts}>
|
|
54
|
-
{children}
|
|
55
|
-
</ConsentRoot>
|
|
52
|
+
export default defineConsentConfig({ scripts });
|
|
56
53
|
```
|
|
57
54
|
|
|
58
|
-
|
|
59
|
-
`
|
|
60
|
-
|
|
55
|
+
Keep the rest of your config, such as `mode` and `routePrefix`, in the
|
|
56
|
+
same call. `ConsentRoot` reads the config in the browser, so the layout
|
|
57
|
+
keeps passing only `state`. App Router, Pages Router and static export all
|
|
58
|
+
read the same file. See
|
|
59
|
+
[Next.js scripts and embeds](https://v3.c15t.com/docs/frameworks/next/scripts).
|
|
61
60
|
|
|
62
61
|
**TanStack Start**
|
|
63
62
|
|
|
64
|
-
|
|
65
|
-
`ConsentRoot
|
|
63
|
+
Import the configuration into your root route and pass it to the existing
|
|
64
|
+
`ConsentRoot` as a top-level prop. Keep the loader from the
|
|
65
|
+
[TanStack Start quickstart](https://v3.c15t.com/docs/frameworks/tanstack-start/quickstart):
|
|
66
66
|
|
|
67
|
-
```tsx
|
|
68
|
-
import { Outlet } from '@tanstack/react-router';
|
|
69
|
-
import { ConsentRoot } from 'c15t/tanstack-start';
|
|
67
|
+
```tsx title="src/routes/__root.tsx"
|
|
70
68
|
import { scripts } from '../consent-scripts';
|
|
71
69
|
|
|
72
|
-
|
|
73
|
-
const state = Route.useLoaderData();
|
|
74
|
-
return (
|
|
75
|
-
<ConsentRoot state={state} backendURL={backendURL} initRoute={false} scripts={scripts}>
|
|
76
|
-
<Outlet />
|
|
77
|
-
{/* Keep your consent banner, dialog and preferences link here. */}
|
|
78
|
-
</ConsentRoot>
|
|
79
|
-
);
|
|
80
|
-
}
|
|
70
|
+
<ConsentRoot state={consent} scripts={scripts}>
|
|
81
71
|
```
|
|
82
72
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
instead. Do not return script callbacks from a server function or route loader.
|
|
73
|
+
Import vendor helpers in the root route module, not in a server function.
|
|
74
|
+
A server function's return value must be serializable, and script
|
|
75
|
+
configurations carry callbacks. See
|
|
76
|
+
[TanStack Start scripts](https://v3.c15t.com/docs/frameworks/tanstack-start/scripts).
|
|
88
77
|
|
|
89
78
|
**React**
|
|
90
79
|
|
|
91
|
-
|
|
80
|
+
Add the configuration to the existing `ConsentProvider` options, next to
|
|
81
|
+
`mode`:
|
|
92
82
|
|
|
93
|
-
```
|
|
94
|
-
import { ConsentProvider } from 'c15t/react';
|
|
83
|
+
```tsx title="src/consent.tsx"
|
|
95
84
|
import { scripts } from './consent-scripts';
|
|
96
|
-
```
|
|
97
|
-
|
|
98
|
-
Keep the existing options and add `scripts`:
|
|
99
85
|
|
|
100
|
-
|
|
101
|
-
<ConsentProvider options={{ ...consentOptions, scripts }}>
|
|
102
|
-
{children}
|
|
103
|
-
</ConsentProvider>
|
|
86
|
+
<ConsentProvider options={{ mode, scripts }}>
|
|
104
87
|
```
|
|
105
88
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
link inside the provider. See
|
|
89
|
+
`mode` is the `manifest()` value from the
|
|
90
|
+
[React quickstart](../frameworks/react/quickstart.md). Keep the banner,
|
|
91
|
+
dialog and preferences link inside the provider. See
|
|
92
|
+
[React scripts and embeds](../frameworks/react/scripts.md).
|
|
109
93
|
|
|
110
94
|
**Nuxt**
|
|
111
95
|
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
than serialized `nuxt.config.ts` runtime configuration.
|
|
96
|
+
Register the scripts under the `c15t` key in `app/app.config.ts`. Adjust the
|
|
97
|
+
relative import to where you created `consent-scripts.ts`:
|
|
115
98
|
|
|
116
|
-
```
|
|
117
|
-
<script setup lang="ts">
|
|
118
|
-
import { onUnmounted } from 'vue';
|
|
119
|
-
import { createScriptLoader } from 'c15t/modules/script-loader';
|
|
99
|
+
```ts title="app/app.config.ts"
|
|
120
100
|
import { scripts } from '../src/consent-scripts';
|
|
121
101
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
let loader: ReturnType<typeof createScriptLoader> | undefined;
|
|
125
|
-
|
|
126
|
-
const removeMountedHook = nuxtApp.hook('app:mounted', () => {
|
|
127
|
-
loader = createScriptLoader({ kernel, scripts });
|
|
128
|
-
});
|
|
129
|
-
onUnmounted(() => {
|
|
130
|
-
removeMountedHook();
|
|
131
|
-
loader?.dispose();
|
|
102
|
+
export default defineAppConfig({
|
|
103
|
+
c15t: { scripts },
|
|
132
104
|
});
|
|
133
|
-
</script>
|
|
134
|
-
|
|
135
|
-
<template>
|
|
136
|
-
<ConsentRoot />
|
|
137
|
-
<NuxtPage />
|
|
138
|
-
</template>
|
|
139
105
|
```
|
|
140
106
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
107
|
+
The Nuxt module merges this over its options in `nuxt.config.ts` and starts
|
|
108
|
+
one script loader in the browser after hydration, once it has applied the
|
|
109
|
+
visitor's stored choice and privacy signals. Keep `scripts` out of
|
|
110
|
+
`nuxt.config.ts`, which reaches the browser as JSON and drops the vendor
|
|
111
|
+
callbacks. Write the vendor IDs into `consent-scripts.ts`. See
|
|
112
|
+
[Nuxt scripts and embeds](https://v3.c15t.com/docs/frameworks/nuxt/scripts).
|
|
147
113
|
|
|
148
114
|
**Vue**
|
|
149
115
|
|
|
150
|
-
|
|
151
|
-
`App.vue`, whose lifetime covers the application:
|
|
116
|
+
Pass the scripts to the existing `c15tVue` plugin call in `src/main.ts`:
|
|
152
117
|
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
import { onMounted, onUnmounted } from 'vue';
|
|
156
|
-
import { createScriptLoader } from 'c15t/modules/script-loader';
|
|
157
|
-
import { useConsentKernel } from 'c15t/vue/vue-plugin';
|
|
158
|
-
import ConsentRoot from 'c15t/vue/consent-root';
|
|
118
|
+
```ts title="src/main.ts"
|
|
119
|
+
import { c15tVue, manifest } from 'c15t/vue/vue-plugin';
|
|
159
120
|
import { scripts } from './consent-scripts';
|
|
160
121
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
onMounted(() => {
|
|
165
|
-
loader = createScriptLoader({ kernel, scripts });
|
|
122
|
+
app.use(c15tVue, {
|
|
123
|
+
mode: manifest(),
|
|
124
|
+
scripts,
|
|
166
125
|
});
|
|
167
|
-
onUnmounted(() => loader?.dispose());
|
|
168
|
-
</script>
|
|
169
|
-
|
|
170
|
-
<template>
|
|
171
|
-
<ConsentRoot />
|
|
172
|
-
<main>Your application</main>
|
|
173
|
-
</template>
|
|
174
126
|
```
|
|
175
127
|
|
|
176
|
-
Keep your existing
|
|
177
|
-
the
|
|
178
|
-
Do not
|
|
179
|
-
[Vue
|
|
128
|
+
Keep your existing `mode` and other options. The plugin starts one
|
|
129
|
+
script loader when the app mounts, after it has applied the visitor's stored
|
|
130
|
+
choice. Do not also call `createScriptLoader` from a component. See
|
|
131
|
+
[Vue scripts and embeds](https://v3.c15t.com/docs/frameworks/vue/scripts).
|
|
180
132
|
|
|
181
133
|
**Astro**
|
|
182
134
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
```js title="astro.config.mjs"
|
|
188
|
-
import { fileURLToPath } from 'node:url';
|
|
189
|
-
```
|
|
190
|
-
|
|
191
|
-
Add this option to the existing `c15t({ ... })` call. Resolve the path from
|
|
192
|
-
the configuration file because Astro injects the import into a virtual module:
|
|
193
|
-
|
|
194
|
-
```js
|
|
195
|
-
clientEntrypoint: fileURLToPath(new URL('./src/c15t.client.ts', import.meta.url)),
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
Export the scripts from that module:
|
|
135
|
+
Add the scripts to the client entrypoint from the
|
|
136
|
+
[Astro quickstart](https://v3.c15t.com/docs/frameworks/astro/quickstart), `src/c15t.client.ts`,
|
|
137
|
+
which the integration finds on its own. Keep `astro.config.mjs` as it is.
|
|
138
|
+
If the module already exports scripts, combine the two arrays.
|
|
199
139
|
|
|
200
140
|
```ts title="src/c15t.client.ts"
|
|
201
|
-
import type { C15tClientOptionsExtension } from '
|
|
141
|
+
import type { C15tClientOptionsExtension } from 'c15t/astro';
|
|
202
142
|
import { scripts } from './consent-scripts';
|
|
203
143
|
|
|
204
144
|
export default { scripts } satisfies C15tClientOptionsExtension;
|
|
205
145
|
```
|
|
206
146
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
147
|
+
Vendor helpers contain callbacks, and the integration options in
|
|
148
|
+
`astro.config.mjs` are serialized into the page, so do not put helpers in
|
|
149
|
+
the integration's `scripts` option. The integration passes the client
|
|
150
|
+
entrypoint to the one runtime every page shares, including across
|
|
210
151
|
`ClientRouter` navigation.
|
|
211
152
|
|
|
212
153
|
**Svelte**
|
|
@@ -216,73 +157,146 @@ pass them as a top-level prop:
|
|
|
216
157
|
|
|
217
158
|
```svelte title="src/App.svelte"
|
|
218
159
|
<script lang="ts">
|
|
219
|
-
import {
|
|
160
|
+
import { ConsentProvider, manifest } from '@c15t/svelte';
|
|
220
161
|
import { scripts } from './consent-scripts';
|
|
221
|
-
|
|
222
|
-
const backendURL = import.meta.env.VITE_C15T_BACKEND_URL;
|
|
223
|
-
if (!backendURL) throw new Error('Set VITE_C15T_BACKEND_URL');
|
|
224
|
-
const mode = hosted({ url: backendURL });
|
|
225
162
|
</script>
|
|
226
163
|
|
|
227
|
-
<
|
|
164
|
+
<ConsentProvider mode={manifest()} {scripts}>
|
|
228
165
|
<!-- Keep your application, consent UI and preferences link here. -->
|
|
229
|
-
</
|
|
166
|
+
</ConsentProvider>
|
|
230
167
|
```
|
|
231
168
|
|
|
232
|
-
Retain the styles and consent UI from the [Svelte quickstart](https://c15t.com/docs/frameworks/svelte/quickstart).
|
|
169
|
+
Retain the styles and consent UI from the [Svelte quickstart](https://v3.c15t.com/docs/frameworks/svelte/quickstart).
|
|
233
170
|
The provider owns the loader and disposes it on unmount.
|
|
234
171
|
|
|
235
172
|
**SvelteKit**
|
|
236
173
|
|
|
237
|
-
Add the scripts to the existing root layout
|
|
238
|
-
and
|
|
174
|
+
Add the scripts to the existing `ConsentRoot` in the root layout. Keep the
|
|
175
|
+
handle and the layout load from the [SvelteKit quickstart](https://v3.c15t.com/docs/frameworks/sveltekit/quickstart).
|
|
239
176
|
|
|
240
177
|
```svelte title="src/routes/+layout.svelte"
|
|
241
178
|
<script lang="ts">
|
|
242
|
-
import {
|
|
179
|
+
import { ConsentRoot } from '@c15t/svelte';
|
|
243
180
|
import { scripts } from '../consent-scripts';
|
|
244
181
|
|
|
245
182
|
let { children, data } = $props();
|
|
246
|
-
const mode = hosted({ url: data.backendURL });
|
|
247
183
|
</script>
|
|
248
184
|
|
|
249
|
-
<
|
|
185
|
+
<ConsentRoot state={data.consent} {scripts}>
|
|
250
186
|
{@render children()}
|
|
251
187
|
<!-- Keep your consent UI and preferences link here. -->
|
|
252
|
-
</
|
|
188
|
+
</ConsentRoot>
|
|
253
189
|
```
|
|
254
190
|
|
|
255
|
-
Import vendor helpers in the layout component, not in `+layout.server.ts
|
|
256
|
-
|
|
257
|
-
|
|
191
|
+
Import vendor helpers in the layout component, not in `+layout.server.ts`:
|
|
192
|
+
a server load cannot send functions to the browser. Prerendered, static and
|
|
193
|
+
SPA-mode pages use the same `scripts` prop. If you pass an externally owned
|
|
258
194
|
`runtime` to the provider, register scripts when creating that runtime instead.
|
|
259
195
|
|
|
196
|
+
**HTML**
|
|
197
|
+
|
|
198
|
+
The helpers in `@c15t/integrations` are ES modules that need a bundler. On a
|
|
199
|
+
page that loads the c15t script tag, paste the vendor's own snippet instead
|
|
200
|
+
and keep it inert until its category is allowed:
|
|
201
|
+
|
|
202
|
+
```html
|
|
203
|
+
<script type="text/plain" data-c15t-category="measurement">
|
|
204
|
+
// The vendor's snippet, unchanged
|
|
205
|
+
</script>
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Use the category this guide names for the vendor. c15t runs the snippet
|
|
209
|
+
once that category is allowed, and reloads the page when the visitor
|
|
210
|
+
withdraws it. Helper options on this page, such as `loadMode`, do not apply
|
|
211
|
+
to a pasted snippet. See [HTML scripts](https://v3.c15t.com/docs/frameworks/html/scripts).
|
|
212
|
+
|
|
260
213
|
**JavaScript**
|
|
261
214
|
|
|
262
|
-
|
|
263
|
-
`kernel.commands.init()`:
|
|
215
|
+
Pass the scripts to `init()` from `@c15t/browser`, next to your mode:
|
|
264
216
|
|
|
265
217
|
```ts
|
|
266
|
-
import {
|
|
218
|
+
import { init, manifest } from '@c15t/browser';
|
|
267
219
|
import { scripts } from './consent-scripts';
|
|
268
220
|
|
|
269
|
-
const
|
|
221
|
+
const consent = init({
|
|
222
|
+
mode: manifest(),
|
|
223
|
+
scripts,
|
|
224
|
+
});
|
|
270
225
|
```
|
|
271
226
|
|
|
272
|
-
|
|
273
|
-
`
|
|
274
|
-
|
|
275
|
-
|
|
227
|
+
Keep the mode from your quickstart. With
|
|
228
|
+
`createConsentRuntime` from `c15t/runtime`, pass `scripts` to it instead.
|
|
229
|
+
A kernel you create yourself needs a loader from
|
|
230
|
+
`c15t/modules/script-loader`. Attach one loader per kernel. See
|
|
231
|
+
[JavaScript scripts](https://v3.c15t.com/docs/frameworks/javascript/scripts).
|
|
232
|
+
|
|
233
|
+
## Options
|
|
234
|
+
|
|
235
|
+
| Option | Default | Behavior |
|
|
236
|
+
| ---------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
237
|
+
| `id` | Required | Tag ID passed to `gtag('config', ...)` and the loader URL. The helper trims it. Empty or whitespace-only values log an error and the script does not load. |
|
|
238
|
+
| `category` | Required | `measurement` for Analytics, `marketing` for Ads and Floodlight. With `loadMode: 'after-consent'`, `gtag/js` waits for it. With `'always'`, it sets the script's permission, which callbacks receive, but does not delay loading. |
|
|
239
|
+
| `loadMode` | `'always'` | When `gtag/js` loads. See [choose when Google loads](#choose-when-google-loads). |
|
|
240
|
+
| `config` | None | Parameters passed as the third argument to `gtag('config', id, config)`. |
|
|
241
|
+
| `consentMapping` | The table below | Replaces the category-to-Google mapping. |
|
|
242
|
+
|
|
243
|
+
The deprecated `script` option overrides fields of the returned script. Use the
|
|
244
|
+
options above instead.
|
|
276
245
|
|
|
277
|
-
##
|
|
246
|
+
## Choose when Google loads
|
|
278
247
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
Google
|
|
248
|
+
| `loadMode` | Until the category is allowed | After the category is allowed |
|
|
249
|
+
| ----------------- | ------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
250
|
+
| `'always'` | Loads `gtag/js` and sends `consent` `default` with the current permissions, then `config`. | Sends `consent` `update` with the mapped types granted. |
|
|
251
|
+
| `'after-consent'` | Sends nothing to Google. The helper creates no `dataLayer` or `gtag` function. | Loads `gtag/js` once. `consent` `default` carries the current permissions and comes before `config`. Later changes send `update`. |
|
|
252
|
+
|
|
253
|
+
Use `'after-consent'` when your policy forbids any request to Google before
|
|
254
|
+
the visitor opts in:
|
|
255
|
+
|
|
256
|
+
```ts title="src/consent-scripts.ts (partial)"
|
|
257
|
+
gtag({ id: 'G-XXXXXXXXXX', category: 'measurement', loadMode: 'after-consent' }),
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
`'after-consent'` waits for the category to be allowed, not for a recorded
|
|
261
|
+
choice. Under an `opt-in` policy, that happens when the visitor allows it.
|
|
262
|
+
Under an `opt-out` or `none` policy, optional categories are allowed before a
|
|
263
|
+
choice, so `gtag/js` loads on the first page unless a saved refusal or a
|
|
264
|
+
privacy signal restricts the category; see
|
|
265
|
+
[policies](../concepts/policies.md). `necessary` is always allowed, so
|
|
266
|
+
`category: 'necessary'` loads `gtag/js` before a choice in either mode. Use
|
|
267
|
+
`measurement` or `marketing`.
|
|
268
|
+
|
|
269
|
+
This gives up part of Consent Mode. With `'always'`, Google tags send
|
|
270
|
+
cookieless pings while a type is denied, and Google uses them to model
|
|
271
|
+
conversions and behavior for visitors who refused or have not chosen. With
|
|
272
|
+
`'after-consent'`, visitors whose category is denied send nothing, so Google
|
|
273
|
+
has no data to model them from. Reports cover only visitors who allowed the
|
|
274
|
+
category.
|
|
275
|
+
|
|
276
|
+
When the visitor withdraws the category, c15t reloads the page and the new
|
|
277
|
+
page does not load `gtag/js`. With `reloadOnConsentRevoked: false`, the tag
|
|
278
|
+
already running stays on the page and gets an `update` that denies the
|
|
279
|
+
withdrawn types. A later grant reuses it instead of loading a second copy.
|
|
280
|
+
|
|
281
|
+
## Google loads before a choice by default
|
|
282
|
+
|
|
283
|
+
With the default `loadMode: 'always'`, the `googleTagManager` and `gtag`
|
|
284
|
+
helpers set `alwaysLoad: true`. Before the visitor chooses, the helper creates
|
|
285
|
+
the `dataLayer` queue, sends `gtag('consent', 'default', ...)` with the current
|
|
286
|
+
permissions and loads Google's script. After each permission change it sends
|
|
287
|
+
`gtag('consent', 'update', ...)`. Google's tags then adjust what they store and
|
|
288
|
+
send; see Google's
|
|
283
289
|
[Consent Mode overview](https://developers.google.com/tag-platform/security/concepts/consent-mode).
|
|
284
290
|
|
|
285
|
-
|
|
291
|
+
So the browser contacts Google before consent. If your policy requires no
|
|
292
|
+
Google request until the visitor allows it, set `loadMode: 'after-consent'`.
|
|
293
|
+
The helper then creates nothing and requests nothing until its category is
|
|
294
|
+
allowed. When it loads, it sends the `default` command first, with the
|
|
295
|
+
permissions at that moment, and `update` commands after later changes. Under
|
|
296
|
+
an `opt-out` or `none` policy, optional categories are allowed before a
|
|
297
|
+
choice, so the helper loads on the first page.
|
|
298
|
+
|
|
299
|
+
## How categories map to Google consent types
|
|
286
300
|
|
|
287
301
|
| c15t category | Google consent types |
|
|
288
302
|
| --------------- | -------------------------------------------------- |
|
|
@@ -292,14 +306,44 @@ The default mapping is:
|
|
|
292
306
|
| `marketing` | `ad_storage`, `ad_user_data`, `ad_personalization` |
|
|
293
307
|
| `experience` | `personalization_storage` |
|
|
294
308
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
309
|
+
Each Google type is `granted` when its category is allowed and `denied`
|
|
310
|
+
otherwise. If a visitor turns off the helper's vendor, every optional type is
|
|
311
|
+
sent as `denied`. The `consentMapping` option replaces the whole table, so
|
|
312
|
+
include every category you still want signalled.
|
|
313
|
+
|
|
314
|
+
Under an opt-out policy, the default command can grant types before the
|
|
315
|
+
visitor has chosen anything. That is a permission, not a recorded choice.
|
|
316
|
+
|
|
317
|
+
## Verify the Google tag
|
|
318
|
+
|
|
319
|
+
On a plain HTML page with the script tag, you gate Google's snippet instead
|
|
320
|
+
and it loads only after consent; see
|
|
321
|
+
[HTML scripts](https://v3.c15t.com/docs/frameworks/html/scripts#google-consent-mode-and-tag-managers).
|
|
322
|
+
|
|
323
|
+
With the default `loadMode: 'always'`:
|
|
324
|
+
|
|
325
|
+
1. In a private window with an opt-in policy, load the page. `gtag/js` loads.
|
|
326
|
+
In Google Tag Assistant, the `consent` `default` command comes before
|
|
327
|
+
`config`, with `analytics_storage` and `ad_storage` set to `denied`.
|
|
328
|
+
2. Open Privacy settings and allow the tag's category. Tag Assistant shows an
|
|
329
|
+
`update` command that grants the mapped types.
|
|
330
|
+
3. Turn the category off again and save. c15t reloads the page, and the new
|
|
331
|
+
page starts with those types denied.
|
|
332
|
+
|
|
333
|
+
With `loadMode: 'after-consent'`:
|
|
334
|
+
|
|
335
|
+
1. In a private window with an opt-in policy, filter DevTools Network by
|
|
336
|
+
`google` and load the page. No request appears, and `window.dataLayer` is
|
|
337
|
+
`undefined` in the Console.
|
|
338
|
+
2. Allow the tag's category. `gtag/js` loads once. In Tag Assistant, the first
|
|
339
|
+
command is `consent` `default` with the mapped types granted, before
|
|
340
|
+
`config`.
|
|
341
|
+
3. Turn the category off again and save. c15t reloads the page, and the new
|
|
342
|
+
page makes no request to Google.
|
|
299
343
|
|
|
300
|
-
|
|
344
|
+
In either mode, with client-side navigation, check that each route change
|
|
345
|
+
sends one page view. A separate router integration that also sends
|
|
346
|
+
`page_view` doubles the count.
|
|
301
347
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
behavior during client navigation so a separate routing integration does not
|
|
305
|
-
send duplicate events or bypass your chosen consent behavior.
|
|
348
|
+
See the [consent verification guide](../guides/verify-consent.md) for hosting
|
|
349
|
+
checks.
|