UI Widget — API Methods
After creating a ConsentiSetup instance, the returned object exposes these methods. Only methods the developer needs to call are public — internal state is protected.
Quick reference
| Method | Returns | Description |
|---|---|---|
| Consent state | ||
hasConsent() | boolean | True if a valid consent record exists for the current profile |
getConsent() | ConsentValue | null | The current consent values keyed by cookie ID |
getGTMConsent() | Record<string, string> | null | Consent in GTM / Google Consent Mode v2 format |
getConsentDate() | Date | false | Date of most recent consent submission, or false if none |
isCookieGranted(cookieId, requestValue?) | boolean | ConsentStatus | Check if a single cookie is granted. Pass true as second arg to get the raw status string instead of a boolean |
isCategoryGranted(categoryId, requestValue?) | boolean | {[id: string]: ConsentStatus}[] | True when every cookie in the category is granted. Pass true to get an array of per-cookie status records |
| Bulk actions | ||
grantAll(onlyMandatory?) | Promise<void> | Accept all cookies. Pass true to grant only mandatory and deny the rest |
denyAll(includingMandatory?) | Promise<void> | Deny all non-mandatory cookies. Pass true to deny mandatory too (logs a warning) |
| Visibility | ||
showBanner(gpc?) | void | Programmatically show the main (or GPC) banner |
hideBanner() | void | Hide the banner |
showModal() | void | Open the preference modal |
hideModal() | void | Close the preference modal |
bannerVisibility() | 'main' | 'gpc' | false | Current banner state |
modalVisibility() | 'preference' | false | Current modal state |
| Events | ||
on(event, handler) | void | Subscribe to a typed widget event. The consenti: prefix is optional |
off(event, handler) | void | Unsubscribe a previously registered handler (pass the same function reference) |
| Lifecycle | ||
init() | Promise<void> | Manually start initialisation — required when autoInit: false |
onReady(cb) | void | Register a callback fired when the widget is fully initialised |
switchLocale(locale) | void | Switch the active locale and re-render the widget |
submitConsent(consent) | Promise<void> | Submit consent programmatically |
deleteConsent() | Promise<void> | Delete consent record (cookie + backend) |
reConsent() | Promise<void> | Delete consent and re-open the banner |
destroy() | void | Unmount the widget and remove all event listeners |
| Runtime configuration | ||
setDarkMode(enable?) | void | Toggle or set dark mode without re-initialising. Omit enable to toggle |
setTheme(theme) | void | Merge CSS token overrides into the current theme at runtime |
setConfig(config) | void | Deep-merge a partial config. Re-applies theme/dark mode side-effects; does not re-init |
setProfile(override) | void | Merge a partial profile override and re-render visible UI without a network call |
| Diagnostics | ||
version() | { package, profileVersion, consentVersion } | Package version and active profile/consent version numbers |
Method details
init()
Manually triggers widget initialisation. Normally called automatically on construction. Set autoInit: false in ConsentiConfig to disable auto-start — for example when the mount point (rootEl) is rendered after the widget is created.
const widget = new ConsentiSetup({
core: {},
rootEl: '#consent-mount',
autoInit: false,
})
// Later, once #consent-mount is available in the DOM:
await widget.init()
widget.onReady(() => {
console.log('Widget ready:', widget.hasConsent())
})init() is also useful after destroy() to re-initialise the same instance rather than creating a new one.
widget.destroy()
// Swap config or wait for a condition, then:
await widget.init()init() while a previous call is still in progress is a no-op — only one initialisation can run at a time per instance.switchLocale(locale)
Switches the active locale, re-resolves the profile, and re-renders the widget with the new language. The locale switcher UI calls this automatically when the user picks a language. You can also call it programmatically.
widget.switchLocale('fr') // switch to French
widget.switchLocale('de-AT') // switch to Austrian GermanThe profile must have multiple locales configured for the switcher to be useful. See Configuration → Locale switcher for setup details.
onReady(callback)
Called once the profile has resolved and the banner state has been determined. Safe to call before or after the widget has initialised.
widget.onReady(() => {
console.log('Widget ready. Has consent:', widget.hasConsent())
})hasConsent()
if (!widget.hasConsent()) {
widget.showBanner()
}getConsent()
const consent = widget.getConsent()
// { analytics: 'granted', marketing: 'denied', necessary: 'granted' }
if (consent?.analytics === 'granted') {
initAnalytics()
}getGTMConsent()
Returns consent in the exact shape Google Tag Manager expects for Consent Mode v2:
const gtm = widget.getGTMConsent()
// {
// analytics_storage: 'granted',
// ad_storage: 'denied',
// ad_user_data: 'denied',
// ad_personalization: 'denied',
// functionality_storage: 'granted',
// }submitConsent(consent)
Programmatically submit consent — useful for custom UI flows:
await widget.submitConsent({
analytics: 'granted',
marketing: 'denied',
necessary: 'granted',
})mandatory: true) are always 'granted' regardless of what you pass. Passing 'denied' for a mandatory cookie is silently ignored.reConsent()
Deletes the existing consent record and re-opens the banner. Use for "Change cookie settings" buttons:
document.querySelector('#change-cookie-settings')?.addEventListener('click', () => {
widget.reConsent()
})isCookieGranted(cookieId, requestValue?)
The most common gating pattern — check whether a single cookie is 'granted'without manually inspecting getConsent().
// Boolean mode (default) — true if granted
if (widget.isCookieGranted('analytics_storage')) {
initAnalytics()
}
// Value mode — returns the raw ConsentStatus string, or false if not in the consent map
const status = widget.isCookieGranted('marketing', true)
// 'granted' | 'denied' | 'objected' | falseDuring SSR or before init() completes, always returns false.
isCategoryGranted(categoryId, requestValue?)
Category-level consent check. The categoryId must match a Category.idin the profile's preference modal.
// Boolean mode — true only when ALL cookies in the category are 'granted'
if (widget.isCategoryGranted('cat-analytics')) {
loadHeatmaps()
}
// Value mode — one record per cookie in the category
const statuses = widget.isCategoryGranted('cat-marketing', true)
// [{ ad_storage: 'granted' }, { ad_personalization: 'denied' }]Returns false / [] if the category ID is not found or the widget is not yet initialised.
grantAll(onlyMandatory?)
Programmatically accept cookies without the user interacting with the banner. Dismisses the banner after submitting.
// Accept everything
await widget.grantAll()
// Accept only mandatory cookies — deny the rest (useful for "Reject all" variants)
await widget.grantAll(true)denyAll(includingMandatory?)
Programmatically deny all non-mandatory cookies. Dismisses the banner after submitting.
// Deny non-mandatory; mandatory cookies stay 'granted'
await widget.denyAll()
// Deny everything including mandatory — use with caution
await widget.denyAll(true)true to denyAll denies mandatory cookies. This is intentionally allowed for testing and special integrations, but will log a console.warn as a reminder.on(event, handler) / off(event, handler)
Typed event subscription API — a cleaner alternative to window.addEventListener. The consenti: prefix on the event name is optional; both forms are accepted.
import type { ConsentEvent } from '@consenti/ui'
const handler = (data: ConsentEvent) => {
console.log('Consent saved:', data.consent)
console.log('Action:', data.consentAction) // 'accept_all' | 'reject_all' | 'custom' | 'update'
}
// Subscribe — both are equivalent
widget.on('consentSubmitted', handler)
widget.on('consenti:consentSubmitted', handler)
// Unsubscribe — must pass the same function reference
widget.off('consentSubmitted', handler)
// All supported event names:
// 'bannerInitialized' — widget initialised; hasExistingConsent is in the detail
// 'bannerVisibility' — banner showed or hid; show / action flags in detail
// 'modalVisibility' — modal opened or closed
// 'consentBeingSubmitted' — user clicked a button (before API call)
// 'consentSubmitted' — consent saved (cookie written + API call if configured)on() / off() use the same underlying DOM events as raw window.addEventListener calls. Both can coexist in the same page. Registered handlers are automatically cleaned up when destroy() is called.setDarkMode(enable?)
Toggle or set dark mode at runtime without re-initialising the widget. The dark class is applied to both the banner root and the preference modal.
widget.setDarkMode() // toggle current state
widget.setDarkMode(true) // force dark
widget.setDarkMode(false) // force light
// Typical use: follow the OS preference and update live
const mq = window.matchMedia('(prefers-color-scheme: dark)')
widget.setDarkMode(mq.matches)
mq.addEventListener('change', (e) => widget.setDarkMode(e.matches))setTheme(theme)
Merge CSS token overrides into the current theme at runtime. CSS custom properties on the root element update immediately — no page reload required.
// Switch primary colour on the fly (e.g. white-label tenant switch)
widget.setTheme({ primaryColor: '#d32f2f', primaryTextColor: '#ffffff' })
// Only the provided keys are updated — other theme values are preserved
widget.setTheme({ borderRadius: '0px' })setConfig(config)
Deep-merges a partial ConsentiConfig into the current config without re-initialising. Theme and dark mode side-effects are re-applied immediately. For locale or profile changes, follow up with switchLocale() or init().
// Update theme and dark mode together
widget.setConfig({
darkMode: true,
core: { theme: { primaryColor: '#1a73e8' } },
})
// Disable powered-by branding at runtime
widget.setConfig({ hidePoweredBy: true })setProfile(override)
Merges a partial profile override into the active profile and re-renders any currently visible banner or modal — no network call is made. Useful for A/B testing copy or dynamically adjusting the banner text after init.
// Change the banner heading live
widget.setProfile({
mainBanner: { heading: 'We care about your privacy' },
})
// Swap the modal position
widget.setProfile({
preferenceModal: { position: 'left' },
})setProfile is a no-op before init() completes — the resolved base profile must exist for the merge to run.version()
Returns the package version and the currently active profile and consent version numbers. Useful for support diagnostics and feature flags.
const info = widget.version()
// {
// package: '0.1.1', — npm package version
// profileVersion: 3, — profile.version from the API or local profile
// consentVersion: 1, — consent schema version (increments on breaking cookie format changes)
// }
console.log(`Consenti ${info.package} | profile v${info.profileVersion}`)destroy()
Removes the banner DOM, modal DOM, BroadcastChannel listener, and all event listeners (including those registered via on()). Call when unmounting in SPA route changes if you manage the lifecycle manually.
// In a SPA router's cleanup callback:
widget.destroy()