Consenti
Tutorial — Frontend + Backend — Step 6 of 9

Events

Subscribe to consenti: events on the frontend and eventBus on the backend.

Both halves fire their own typed events. Subscribe to whichever your integration needs — each snippet is independent.

Frontend events (widget.on)

consentSubmitted

ts
widget.on('consentSubmitted', ({ consentJson, visitorId, apiResponse }) => {
  console.log('Saved server-side as:', apiResponse.id, 'for visitor', visitorId)
})

bannerInitialized / bannerVisibility / modalVisibility

ts
widget.on('bannerInitialized', ({ complianceGroup, willShow }) => {
  console.log('Compliance group:', complianceGroup, '— will show banner:', willShow)
})

widget.on('bannerVisibility', ({ visible, variant }) => {
  console.log(variant, 'banner is now', visible ? 'visible' : 'hidden')
})

widget.on('modalVisibility', ({ visible }) => {
  console.log('Preference modal is now', visible ? 'open' : 'closed')
})

consentBeingSubmitted / parentalConsentRequired

ts
widget.on('consentBeingSubmitted', ({ consentAction }) => {
  console.log('About to save:', consentAction) // fires before the API call
})

widget.on('parentalConsentRequired', ({ parentalConsentToken, visitorId }) => {
  sendParentalConsentEmail(visitorId, parentalConsentToken)
})

Full payload shapes in the UI Events reference.

Backend events (eventBus)

createConsenti() returns an eventBus — a standard Node.js EventEmitter — for hooking into every data lifecycle step without touching routes.

consent.created / consent.updated / consent.erased

ts
const { eventBus } = createConsenti({ /* ... */ })

eventBus.on('consent.created', (record) => {
  console.log('New consent record:', record.visitorId)
})
eventBus.on('consent.updated', ({ previous, current }) => {
  console.log('Consent changed for', current.visitorId)
})
eventBus.on('consent.erased', ({ visitorId }) => {
  myDmpClient.deleteVisitor(visitorId) // GDPR right-to-erasure fired
})

visitor.created

ts
eventBus.on('visitor.created', (visitor) => {
  console.log('New visitor in region:', visitor.region ?? 'unknown')
})

profile.created / profile.updated / profile.deleted

ts
eventBus.on('profile.created', (profile) => {
  console.log('New profile:', profile.id, 'v' + profile.version)
})
eventBus.on('profile.updated', ({ previous, current }) => {
  console.log('Profile', current.id, 'bumped to v' + current.version)
})
eventBus.on('profile.deleted', ({ id, previous }) => {
  console.log('Profile deleted:', id, '(was v' + previous.version + ')')
})

cache:warm / cache:purge — CDN invalidation

ts
eventBus.on('cache:warm', ({ paths }) => {
  for (const p of paths) cdnClient.warmPath(p)
})
eventBus.on('cache:purge', ({ paths }) => {
  for (const p of paths) cdnClient.purge(p)
})

ready

ts
// Promise form (preferred for startup sequencing)
await consenti.ready
server.listen(3000)

// Event form (fire-and-forget side effects)
eventBus.on('ready', () => console.log('[consenti] backend ready'))

Full reference for every event and payload shape in API Events.