Skip to main content

Svelte Consent API

Callbacks

Pick the right callback

Run your own code when consent changes through the provider's callbacks prop, a script's own callbacks, or a kernel event in one component:

You want toUse
Send a choice to your analytics or CRM when the visitor makes onecallbacks.onChoiceRecorded
Start or stop your own code when what may run changescallbacks.onPermissionsChanged
Report failed backend requestscallbacks.onError
Show a message or flush data before a withdrawal reloads the pagecallbacks.onBeforeConsentRevocationReload
Call a vendor's own consent API after its script loadsThe script's onConsentChange
React to consent inside one componentgetConsentKernel().events.on() or the manager's properties

onChoiceRecorded or onPermissionsChanged

onChoiceRecorded runs only when the visitor accepts, rejects or saves. onPermissionsChanged runs whenever effective permissions change, whatever the cause:

EventonChoiceRecordedonPermissionsChanged
Visitor accepts, rejects or savesYesYes, if a permission changed
Policy resolves under opt-out and allows categories before a choiceNoYes
Global Privacy Control overrides a grantNoYes
A recorded choice expiresNoYes
Visitor dismisses a noticeNoNo

Use onChoiceRecorded for consent records and audit trails, because it fires only for a visitor's action. Use onPermissionsChanged to start or stop code, because it covers every way a permission changes. Never treat onPermissionsChanged as proof that the visitor agreed to something.

Pass callbacks to the provider

src/lib/consent-callbacks.ts
import type { ConsentProviderCallbacks } from '@c15t/svelte';

// Pass as `callbacks={callbacks}` on ConsentProvider.
export const callbacks: ConsentProviderCallbacks = {
	// Runs just before c15t reloads the page after a withdrawal.
	onBeforeConsentRevocationReload: ({ preferences }) => {
		console.info('Reloading with', preferences);
	},
	// An explicit accept, reject or save. Never runs for defaults, expiry,
	// policy changes or privacy signals.
	onChoiceRecorded: ({ snapshot, confirmed }) => {
		console.info('Visitor chose', snapshot.explicitChoice, confirmed);
	},
	// A failed command, such as an /init request that could not reach the
	// backend.
	onError: ({ error }) => {
		console.warn('c15t error', error);
	},
	// Any change to what may run, whatever caused it.
	onPermissionsChanged: ({ snapshot, previous }) => {
		console.info('Permissions', previous, '->', snapshot.effectivePermissions);
	},
};

Pass the object as callbacks={callbacks} on ConsentProvider. The provider reads it once, when it is created. Keep the functions in a module or in the component that renders the provider; on SvelteKit, not in a server load, because a load cannot send functions to the browser.

CallbackPayload
onChoiceRecordedsnapshot, the state after the choice; confirmed, the categories this action recorded; actionAt, the time.
onPermissionsChangedsnapshot, the state after the change; previous, the permissions before it.
onErrorerror, a message string.
onBeforeConsentRevocationReloadpreferences, the permissions after the withdrawal.

Callbacks run after c15t updates its own state, so snapshot and getConsentManager() already hold the new values. Visitor actions happen in the browser, so in practice that is where the callbacks run.

onBeforeConsentRevocationReload runs synchronously right before the reload. Keep it short; the page is about to unload. It does not run when you set reloadOnConsentRevoked={false}.

Script callbacks

Each entry in scripts takes its own callbacks:

CallbackRuns
onBeforeLoadBefore the loader adds the script.
onLoadWhen the script loaded.
onErrorWhen the script failed to load.
onConsentChangeWhen consent changes after the script loaded. Use it to call the vendor's own consent API.
onDisposeWhen the configuration is removed or the provider unmounts.

Helpers from @c15t/integrations already set these for their vendor. Building integrations shows how to write them.

Listen inside one component

For a component that shows or reacts to consent, subscribe to a kernel event in $effect, so the listener goes away with the component. The context getters page has the example. For values you render, read the manager's properties instead; they update the component without a listener.

Verify the callbacks

Open the console, clear site data and reload:

  1. Accept in the banner. onChoiceRecorded and onPermissionsChanged both log.
  2. Dismiss a notice, if your policy shows one. Neither logs.
  3. Withdraw a category you allowed. onBeforeConsentRevocationReload logs, then the page reloads.