Changelog
1.0.0
Major Changes
- 452d11b: First stable release. The public API now follows semantic versioning: breaking changes wait for 2.0.0. If you used a release candidate or the earlier internal package, follow Migrating to 1.0.
Minor Changes
-
3bec6da: Every provider and server destination takes an
eventsoption: the event namestrack()sends to it, orfalsefor none. Analytics providers receive every event by default. The Meta and TikTok pixels,metaCapiandtiktokEventsnow receive only events that map to one of their standard events; custom and auto-tracking events reach them only when listed. An event whoseonlyoption names a provider is always sent to it.autoTracking()no longer takesonly; use the providers’eventsoption instead.Declare your own events in a
Registerinterface (declare module 'consentlayer' { interface Register { events: { … } } }) to type their params. Once declared,track()rejects undeclared names. -
dfe1789: When a visitor grants marketing after analytics on the same route, the automatic page view now reaches marketing server destinations such as the Meta Conversions API, without being sent twice to those that already have it.
page()’sserveroption accepts an array of categories, andServerEventhas acategoriesfield thatsendServerEventhonors. -
dfe1789: Add a
nonceoption tocreateAnalytics(). ConsentLayer sets it on every script it injects, including the inline base code ofmeta()andtiktok(), for a Content Security Policy that allows scripts by nonce. The script-tag build reads it from its own<script>tag. -
dfe1789:
tcf()no longer stores the denied state it reads while the CMP shows its interface, before the visitor has chosen. Consent adapters can answer{ consent, provisional: true }frombootstrap()for such a state: the engine applies it but does not store it. The newConsentBootstrapAnswertype describes the answer.
Patch Changes
- 2d887e6:
closeDialog()now resetsprefsto the stored choice, so toggles a visitor changed and then closed without saving are no longer granted by a later Save. - 15982df: Export the
StoredConsenttype fromconsentlayer, so a customConsentStorageAdaptercan name the record it reads and writes. - fefddf8: A server destination’s
eventsoption now coverspage_viewas well, sometaCapi({ events: ['lead'] })no longer receives page views.createAnalyticsHandleranswers with aconsentlayer-eventsheader listing the event names its destinations take, and the browser then forwards only those events, plus events withonly, instead of every event.
1.0.0-rc.2
Patch Changes
- 15982df: Export the
StoredConsenttype fromconsentlayer, so a customConsentStorageAdaptercan name the record it reads and writes. - fefddf8: A server destination’s
eventsoption now coverspage_viewas well, sometaCapi({ events: ['lead'] })no longer receives page views.createAnalyticsHandleranswers with aconsentlayer-eventsheader listing the event names its destinations take, and the browser then forwards only those events, plus events withonly, instead of every event.
1.0.0-rc.1
Minor Changes
-
3bec6da: Every provider and server destination takes an
eventsoption: the event namestrack()sends to it, orfalsefor none. Analytics providers receive every event by default. The Meta and TikTok pixels,metaCapiandtiktokEventsnow receive only events that map to one of their standard events; custom and auto-tracking events reach them only when listed. An event whoseonlyoption names a provider is always sent to it.autoTracking()no longer takesonly; use the providers’eventsoption instead.Declare your own events in a
Registerinterface (declare module 'consentlayer' { interface Register { events: { … } } }) to type their params. Once declared,track()rejects undeclared names. -
dfe1789: When a visitor grants marketing after analytics on the same route, the automatic page view now reaches marketing server destinations such as the Meta Conversions API, without being sent twice to those that already have it.
page()’sserveroption accepts an array of categories, andServerEventhas acategoriesfield thatsendServerEventhonors. -
dfe1789: Add a
nonceoption tocreateAnalytics(). ConsentLayer sets it on every script it injects, including the inline base code ofmeta()andtiktok(), for a Content Security Policy that allows scripts by nonce. The script-tag build reads it from its own<script>tag. -
dfe1789:
tcf()no longer stores the denied state it reads while the CMP shows its interface, before the visitor has chosen. Consent adapters can answer{ consent, provisional: true }frombootstrap()for such a state: the engine applies it but does not store it. The newConsentBootstrapAnswertype describes the answer.
Patch Changes
- 70c4160: Updates development dependencies and fixes the lint errors the newer typescript-eslint reports. The script tag now binds
history.pushStateandreplaceStateonce, with no change in behavior.
1.0.0-rc.0
The first public release.
Consent
createAnalytics()returns one instance withtrack,page,identify,reset,group,captureErrorandconsent. Each provider runs only while its consent category is granted; calls made before boot are held and delivered in order.- Categories
preferences,analyticsandmarketing, plus typed custom categories declared inConsentCategories. createConsentController()and each framework binding expose the state a banner needs; build your own banner on it.- Re-consent after
consent.maxAgeDaysor a new majorconsent.policyVersion, withonStale: 'discard' | 'keep'. - Global Privacy Control: while the browser sends it,
acceptAll()leavesmarketingdenied; an explicit opt-in still wins.consent.gpc: falseturns it off. The server follows each event’s consent, which already reflects the signal. - Consent records:
createConsentHandler()appends each choice to Postgres, Supabase, Prisma, Drizzle or Upstash and sets a signed consent cookie, whichcreateAnalyticsHandler({ consentCookie })uses to deny what the request body grants beyond it. A lost cookie is restored from the browser’s stored choice.
Consent adapters
tcf()fromconsentlayer/adapters/tcffollows the choice an IAB TCF v2 CMP collects, read-only, ahead of the stored choice.shopifyCustomerPrivacy()fromconsentlayer/adapters/shopifykeeps Shopify’s Customer Privacy API in sync, and loads it on headless storefronts.googleConsentMode()fromconsentlayer/adapters/google-consent-modesends Consent Mode v2 signals to every Google tag, with region defaults,waitForUpdate,urlPassthroughandadsDataRedaction.
Providers
ga4(): Google Analytics 4 with Consent Mode v2, basic or advanced, andserverContainerUrlfor server-side tagging.gtm(): a Google Tag Manager container, loaded after the Consent Mode defaults, fed page views, events, the user ID and consent changes throughdataLayer.requiredConsentholds it until a category is granted, andserverContainerUrlloads it from your tagging server.meta(): the Meta Pixel with advanced matching and event IDs shared with the Conversions API.tiktok(): the TikTok Pixel with TikTok’s consent mode and advanced matching.posthog(): cookieless until analytics consent; events, identity, groups, errors, and opt-in autocapture and session recording.sentry(): errors without consent or personal data; the user ID, Replay and tracing after analytics consent.consentlayer/sentry/serverandconsentlayer/sentry/nextfor Next.js.contentsquare(),vercel(), andhotjar()(deprecated in favor ofcontentsquare()).definePlugin()andloadScript()fromconsentlayer, andcheckPlugin()fromconsentlayer/testing, for writing your own provider.- Standard events with GA4 names, translated for each provider, and
productParams,cartParamsandorderParamsinconsentlayer/ecommerce. autoTracking()fromconsentlayer/auto-tracking: page sessions, scroll depth, time on page and clicks.<MetaPixelNoscript>and<GtmNoscript>render the vendors’<noscript>markup for visitors without JavaScript, opt-in.
Server
createAnalyticsHandler()forwards browser events to server destinations;sendServerEvent()sends server-only events such as webhooks. Both check the event’s consent, hash email addresses and phone numbers, and run on edge runtimes.- Destinations:
metaCapi()(Meta Conversions API),tiktokEvents()(TikTok Events API),sgtm()(a server-side Google Tag Manager container) andga4Server()(GA4 Measurement Protocol, server-only events).
Frameworks
consentlayer/reactandconsentlayer/next(App Router and Pages Router).consentlayer/vueand theconsentlayer/nuxtmodule.consentlayer/svelteandconsentlayer/sveltekit.consentlayer/solidandconsentlayer/solidstart.consentlayer/angular.- A script-tag build on jsDelivr and unpkg, configured with
window.ConsentLayerordata-attributes, with an optional consent banner.
Debugging
debuglogs consent changes, page views, events, provider lifecycle and errors; its object form picks topics and providers and takes your own logger.onErrorreports script-load failures and plugin errors.