JavaScript API

Everything below is live — this page runs ConsentLoop. Press ▶ run buttons and watch the widget and the event log react. The same API is available as ESM named exports and on window.ConsentLoop (CDN builds).

Methods

run(config?) → Promise<API>

Boot the widget. Idempotent — safe to call from multiple entry points; SSR-safe (no-op without window). Resolves once consent is applied or the banner is up.

show() / hide()

Show or hide the first-layer banner.

showPreferences() / hidePreferences()

Open or close the second layer. Wire showPreferences() to your footer’s “Cookie settings” link — required by GDPR to make withdrawal as easy as consent.

acceptAll() / rejectAll()

One-call decisions. Persist, activate/clear, fire hooks, update Consent Mode.

accept(categories, services?)

Fine-grained consent. Required categories are always included; services default to “all of the category” unless you pass a subset.

isAccepted(category) → boolean

Current effective state (includes implied consent under opt-out regimes).

isServiceAccepted(category, service) → boolean
acceptedCategories() → string[]
getConsent() → ConsentRecord | null

The full record: id, timestamps, revision, accepted/rejected, services, regulation, method (explicit vs implied), library version. This is what adapters receive for audit trails.

hasConsent() → boolean

true only for a stored, non-expired, current-revision choice.

setLanguage(lang) → Promise

Re-renders the widget live. URL-based translations are fetched on demand and cached.

rescan()

Re-scan the DOM for gated elements (SPA route changes).

reset(reprompt = true)

Erase stored consent (new consent id on next choice) and optionally re-show the banner.

on(event, cb) → unsubscribe

Subscribe to lifecycle events — see below. Also emitted as DOM events on window (consentloop:*) for analytics tools and tag managers.

destroy()

Remove the widget and all listeners. For tests and hard SPA teardowns.

Events

Names for on() and as DOM events (consentloop:<name>):

EventDetailWhen
readyBoot finished (consent applied or banner shown).
consentConsentRecordConsent is known: every load with valid consent + after every change.
first-consentConsentRecordFirst explicit choice of this visitor.
change{ record, changed }An existing choice was modified.
banner-show/hide, preferences-show/hideUI lifecycle.

Live event log

Interact with the widget to see events…

Hooks (config)

ConsentLoop.run({
  hooks: {
    onFirstConsent: (record) => analytics.track("consent_given", record),
    onConsent: (record) => bootServices(record),        // every load once known
    onChange: (record, changed) => syncServices(changed),
    onBannerShow: () => {},  onBannerHide: () => {},
    onPreferencesShow: () => {},  onPreferencesHide: () => {},
  },
});

The consent record

{
  id: "9f5c…",              // rotates on reset()
  firstAt: "2026-07-20T12:00:00.000Z",
  updatedAt: "2026-07-20T12:00:00.000Z",
  revision: 0,
  accepted: ["necessary", "analytics"],
  rejected: ["marketing"],
  services: { analytics: ["ga4", "plausible"] },
  regulation: "gdpr",
  method: "explicit",        // or "implied" (opt-out regimes)
  v: "0.1.0"
}

Stored compactly (short keys) in a first-party cookie (default, server-readable) or localStorage. Server-side you can parse the cookie to make consent-aware rendering decisions.