UI Widget — Events
Consenti fires custom DOM events on window at every consent lifecycle step. All events are prefixed consenti: and carry a typed detail payload.
Event reference
| Event | Fired when |
|---|---|
consenti:bannerInitialized | Widget initialises and determines whether to show the banner |
consenti:bannerVisibility | Banner shows or hides |
consenti:modalVisibility | Preference modal shows or hides |
consenti:consentBeingSubmitted | User clicked a consent button (before API call) |
consenti:consentSubmitted | Consent saved (cookie written + API call if configured) |
Typed API — on() / off()
The recommended way to subscribe to events is widget.on() / widget.off(). This API is typed, handles the CustomEvent unwrapping for you, and cleans up automatically when widget.destroy() is called. The consenti: prefix on the event name is optional.
import type { ConsentEvent } from '@consenti/ui'
const handler = (data: ConsentEvent) => {
console.log('Consent saved:', data.consent)
console.log('Action:', data.consentAction)
console.log('GPC detected:', data.gpcDetected)
}
widget.on('consentSubmitted', handler) // 'consenti:' prefix is optional
widget.off('consentSubmitted', handler) // must pass the same function referenceRaw DOM listeners
Raw window.addEventListener calls work too and can coexist with on():
import type { ConsentEvent } from '@consenti/ui'
window.addEventListener('consenti:consentSubmitted', (e: Event) => {
const detail = (e as CustomEvent<ConsentEvent>).detail
console.log('Consent action:', detail.consentAction) // 'accept_all' | 'reject_all' | 'custom' | 'update'
console.log('Consent values:', detail.consent) // { analytics: 'granted', marketing: 'denied', ... }
console.log('Page URL:', detail.pageUrl)
console.log('GPC detected:', detail.gpcDetected)
})Detail types
BannerInitializedDetail
interface BannerInitializedDetail {
profileId: string
regulation: 'gdpr' | 'ccpa'
hasExistingConsent: boolean // true if valid consent cookie exists
gpcDetected: boolean
willShow: boolean // true if banner will be rendered
}BannerVisibilityDetail
interface BannerVisibilityDetail {
show: boolean // true = banner appeared; false = banner hidden
bannerType: 'main' | 'gpc' // which banner
action: boolean // true = triggered by user button click
}ModalVisibilityDetail
interface ModalVisibilityDetail {
show: boolean // true = modal opened; false = modal closed
action: boolean // true = triggered by user button click
}ConsentSubmittedDetail
interface ConsentSubmittedDetail {
consentId: string // UUID per submission
visitorId: string // visitor UUID (stable across sessions)
profileId: string
profileVersion: number
consentJson: Record<string, ConsentStatus> // { analytics: 'granted', ... }
consentAction: 'accept_all' | 'reject_all' | 'custom' | 'update'
gpcDetected: boolean
pageUrl: string // window.location.href at submission time
timestamp: string // ISO 8601
apiResponse?: unknown // backend response if api.enabled: true
}GTM dataLayer pushes
When utils.gtm.containerId is set, Consenti pushes to window.dataLayerin the standard Google Consent Mode v2 format:
// On initialization (default denied state)
dataLayer.push({
'event': 'consent_default',
'consent_type': 'analytics_storage',
'consent_value': 'denied',
})
// On submission
dataLayer.push({
'event': 'consent_update',
'analytics_storage': 'granted',
'ad_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'functionality_storage': 'granted',
})window.gtag and window.google_tag_managerbefore emitting cookieless pings — no-op pollution is prevented on non-Google sites.ConsentScript — auto-load scripts on consent
ConsentScript watches consenti:consentSubmitted and injects or removes a <script> tag based on whether a specific cookie ID is granted. Consent is also evaluated immediately at construction time so existing consent is honoured without waiting for the next submission event.
import { ConsentScript } from '@consenti/ui'
// bind: true (default) — auto-removes script on consent revoke, re-injects on re-grant
new ConsentScript({
cookieId: 'analytics',
src: 'https://cdn.example.com/analytics.js',
onLoad: () => console.log('Analytics loaded'),
onRevoke: () => console.log('Analytics removed'),
})
// bind: false — check consent once at construction; never attach a change listener
new ConsentScript({
cookieId: 'analytics',
src: 'https://cdn.example.com/analytics.js',
bind: false,
})CookieTrigger — open banner/modal from any element
Attach a trigger to any existing element or let Consenti auto-create a button:
import { CookieTrigger } from '@consenti/ui'
// Attach to existing element
new CookieTrigger({ selector: '#cookie-settings', action: 'modal' })
// Or auto-create a button
new CookieTrigger({
action: 'banner',
label: 'Cookie Settings',
appendTo: document.querySelector('#footer'),
})