Skip to content

Callbacks & Events

The library gives you three ways to react to consent changes: config callbacks, store subscriptions, and a custom event emitter. Choose the one that fits your use case.

Pass callbacks in your createConsent config. They’re set once and persist for the lifetime of the instance.

Fires once — the very first time a user gives consent. Never fires again, even on page reloads where consent is restored from a cookie.

const consent = createConsent({
categories: {
necessary: { readOnly: true },
analytics: {}
} as const,
callbacks: {
onFirstConsent: ({ cookie }) => {
// First time consent — great for logging to your backend
fetch("/api/consent", {
method: "POST",
body: JSON.stringify(cookie)
});
}
}
});

Fires when consent is given for the first time and on every subsequent page load where consent is restored from a cookie.

callbacks: {
onConsent: ({ cookie }) => {
// Fires on page load if consent is already valid
// Also fires right after onFirstConsent
initializeAnalytics(cookie.categories);
},
},

Use this to boot up your tracking scripts on page load when consent is already valid.

Fires whenever categories or services change — accepting, rejecting, toggling individual services.

callbacks: {
onChange: ({ cookie, changedCategories, changedServices }) => {
console.log("Categories changed:", changedCategories);
console.log("Services changed:", changedServices);
// Sync with your analytics
if (changedCategories.includes("analytics")) {
updateGtagConsent(cookie);
}
},
},

consent.subscribe() lets you add reactive listeners that fire on every state change. Use this for syncing UI state or logging.

const unsubscribe = consent.subscribe((state) => {
console.log("New state:", state);
});
// Later, when you're done:
unsubscribe();

Returns an unsubscribe function. The listener receives the full read-only ConsentState snapshot.

In React, useConsent handles this subscription for you — it triggers a re-render on every state change automatically.

consent.on() and consent.off() give you a lightweight pub/sub system. Built-in events mirror the config callbacks:

Event Payload When
"firstConsent" { cookie: CookieValue } First consent action
"consent" { cookie: CookieValue } Consent given or restored from cookie
"change" { cookie: CookieValue } Categories or services changed
consent.on("change", ({ cookie }) => {
document.documentElement.setAttribute("data-consent", cookie.categories.join(","));
});
consent.on("change", ({ cookie }) => {
document.documentElement.setAttribute("data-consent", cookie.categories.join(","));
});

on() returns an unsubscribe function. off() removes a specific listener:

const listener = ({ cookie }) => {
/* ... */
};
consent.on("change", listener);
consent.off("change", listener);
Use case Best choice
Boot up tracking on page load onConsent config callback
Log consent to backend (once) onFirstConsent config callback
Sync UI state continuously subscribe (or useConsent in React)
Run side effects on changes onChange config callback or on("change", ...)
Custom event bus on / off

You can mix and match freely — they all coexist on the same instance.