Svelte Consent API
Context getters
Where getters work
Svelte has no consent hooks or stores. @c15t/svelte exports context getters
instead. Call one at the top level of a component's <script>, inside
ConsentProvider, and read its properties in markup or in $derived.
The properties read the provider's $state, so the component updates when
consent changes.
A getter uses Svelte's getContext, so it throws when you call it:
- in an event handler, an effect or a timer,
- in a component rendered outside the provider,
- in a plain
.tsmodule.
Call it once at the top level and keep the returned object; its methods work
from event handlers later. The same getters are exported from
@c15t/svelte/headless.
| Getter | Returns | Use it to |
|---|---|---|
getConsentManager() | ConsentManagerState | Read permissions and choices, and record choices. Start here. |
getHeadlessConsent() | Surface state and actions | Build your own banner. See headless. |
getIAB() | SvelteIABState or null | Read or change IAB TCF consent. |
getConsentKernel() | ConsentKernel | Subscribe to raw events or call low-level commands. |
getSnapshot() | ConsentSnapshot | Read the full kernel snapshot once. |
Read a permission or a recorded choice
A permission answers "may this run now?" A recorded choice answers "what did the visitor decide?" They differ. Under an opt-out policy a category can be allowed before the visitor chooses anything, and Global Privacy Control can deny a category the visitor allowed. Load scripts and render optional features from permissions; use the recorded choice only to show or report what the visitor decided.
Before the visitor chooses, this component shows "No" and "Not chosen". How consent works explains the difference.
| Property or method | Answers |
|---|---|
has(condition) | Whether a category, or a condition such as { and: ['measurement', 'marketing'] } or { or: [...] }, is allowed now. |
effectivePermissions | Every category's permission, such as effectivePermissions.measurement. |
explicitChoice | The visitor's recorded choice, or null before they choose. explicitChoice.categories.measurement.value is one category's answer. |
noticeDismissal | Whether and when a notice was dismissed. Dismissing a notice is not consent. |
privacySignals | Signals from the browser, such as privacySignals.gpc.detected. |
restrictions | Per category, the reasons a recorded grant is overridden, such as GPC. |
vendorChoice, selectedVendors | Recorded and draft grants for individual vendors outside IAB. |
Read the policy and the UI state
| Property | Value |
|---|---|
hasPolicy | true once a policy resolved for the visitor. Optional categories stay denied until then. |
policyPending | true while the policy request is in flight. |
policyRule | The resolved rule: model, prompt, scope, rights and more. |
resolution | The resolution outcome, with status of matched, failed or another state. |
model | 'opt-in', 'opt-out', 'iab' or 'none'. |
promptRequirement | Whether the visitor owes a choice, a notice acknowledgement or nothing. |
hasConsentUi | Whether the policy calls for any consent surface. |
hasConsentPreferences | Whether a way back to preferences should show. ConsentDialogLink renders on this. |
activeUI | 'banner', 'dialog' or 'none'. |
location | The country and region the policy resolved for. |
overrides | The forced country, region, language or GPC value, if any. |
consentCategories, consentTypes | The categories the preference UI offers, as names and as full definitions. |
translationConfig, translations | The active copy and language. |
legalLinks, presentation | The provider's legalLinks and presentation props. |
user, subject | The identified user and the backend's subject for this visitor. |
Record a choice
Call the methods from event handlers. Save methods return a promise.
Clicking Allow analytics records measurement as allowed and leaves the other categories as they were. Privacy settings opens the dialog.
| Method | Effect |
|---|---|
setActiveUI(surface) | 'dialog' opens preferences, 'banner' shows the banner, 'none' closes the open surface. Closing preferences brings the banner back while the policy still owes a choice. Records nothing. |
setConsent(category, value) | Changes one category in the unsaved draft. setSelectedConsent is the same method. |
setSelectedVendor(vendorId, granted) | Changes one vendor in the draft. Ignored for undeclared or disabled vendors. |
saveConsents('custom') | Records the draft. Throws when the policy changed since the draft started; see the draft. |
saveConsents('all') | Records every category in scope as allowed. |
saveConsents('necessary') | Records only necessary, rejecting the rest. |
dismissNotice() | Records that the visitor dismissed a notice. Only works while a notice is due. |
setLanguage(code) | Switches the language and resolves the policy again for it. |
getDisplayedConsents() | The categories to render in your own preference UI. |
getDisplayedVendors(category) | The vendors to list under one category. Empty under an IAB policy. |
isVendorAllowed(vendorId) | true while a declared vendor's category is allowed and the visitor has not switched it off. false for an id nothing declares. |
subscribeToConsentChanges(listener) | Calls listener with the permissions after every snapshot change. Returns an unsubscribe function. |
A save updates permissions in the same task, so registered scripts and
ConsentGate react before the backend request finishes. A failed request is
kept and retried; it does not undo the choice, and the provider's onError
callback reports it. When a save withdraws a category that was granted, the
provider reloads the page by default so code that already ran is gone. Set
reloadOnConsentRevoked={false} on the provider to handle that yourself.
Only call save methods from a visitor's action. Saving on page load records a choice the visitor never made.
Work with the draft
consent.draft is the unsaved state every preference surface on the page
shares: the dialog, ConsentWidget and your own UI.
| Member | Behavior |
|---|---|
values | Each category's draft value. Starts from the recorded choice, or from the policy's defaults before a choice. A choice saved elsewhere moves the values the visitor has not touched. Categories outside consentCategories read false. selectedConsents is the same object. |
vendors | Each declared vendor's draft grant. |
isStale | true when the policy, the displayed categories or the vendor list changed while the draft held an unsaved change. A draft with no unsaved change follows the policy and is never stale. |
set(category, value), setVendor(id, granted) | The same as setConsent and setSelectedVendor. |
reset() | Discards unsaved changes. |
The draft's code loads with the first preference surface, so a page that
only shows the banner does not ship it. ConsentWidget and ConsentDialog
bring it with them, and their switches render seeded on the first render,
on the server too. Headless code that reads or writes the draft without
either one starts the load itself: until it lands, values and vendors
are empty objects and isStale is false, and they update reactively once
it does. Writes made before then apply in order, draft.reset() drops
them, and saveConsents('custom') waits for the draft before it records.
When isStale is true, saveConsents('custom') throws "The policy changed.
Review your preferences before saving." Show the visitor the current
categories, call draft.reset(), and let them save again.
Read and change IAB TCF consent
getConsentManager().iab is the live IAB state, or null when IAB is off.
getIAB() returns the same object at the moment you call it; read .iab on
the manager for values that update.
| Member | Value or effect |
|---|---|
config.enabled, config.cmpId | Whether the add-on is on, and the CMP ID. |
gvl, isLoadingGVL | The Global Vendor List, and whether it is still loading. |
purposeConsents, vendorConsents, specialFeatureOptIns | The visitor's TCF choices, staged or saved. |
tcString | The saved TC String, or null. |
nonIABVendors | Custom vendors outside the IAB list. |
acceptAll(), rejectAll() | Accept All sets vendor and purpose consent for declared consent purposes, separate vendor and purpose legitimate-interest signals for declared legitimate-interest purposes, and opt-ins for declared special features. Reject All clears these signals. |
setPurposeConsent(id, value), setPurposeLegitimateInterest(id, value) | Change one purpose. |
setVendorConsent(id, value), setVendorLegitimateInterest(id, value) | Change one vendor. |
setSpecialFeatureOptIn(id, value) | Change one special feature. |
save() | Writes the TC String and records the choice. |
preferenceCenterTab, setPreferenceCenterTab(tab) | The tab IABConsentDialog shows. |
Until the TCF add-on finishes loading, the action methods queue and replay. See IAB TCF for setup.
Listen to consent events
getConsentKernel() returns the consent kernel behind the provider. Its
events.on(type, listener) subscribes to one event and returns an
unsubscribe function. Subscribe in $effect so Svelte removes the listener
when the component unmounts:
choice:recorded fires for an explicit accept, reject or save.
permissions:changed fires for any change to what may run. For callbacks that
cover the whole app, use the provider's callbacks prop instead; see
callbacks.
The kernel also has subscribe(listener), which runs on every snapshot
change, getSnapshot(), and commands for init(), save(),
dismissNotice() and identify(). Prefer the manager's methods; they keep
the draft and the open surface in step, which the raw commands do not.
getSnapshot() from @c15t/svelte returns the snapshot at the moment you
call it and does not update.
Other exports
| Export | Purpose |
|---|---|
manifest() | The mode that resolves the policy in the browser from the manifest consentManifest() downloaded. |
hosted({ backendURL }) | The mode that asks an Inth or self-hosted backend's /init for every visitor. |
offline({ policyRules }) | The mode that resolves policies in the browser with no backend. Not recommended for production environments. |
custom(transport) | The mode for your own transport. |
createConsentRuntime(options) | Creates a runtime to share between providers, through their runtime prop. |
resolveConsentPresentation(input) | Resolves the banner or dialog shape and actions a policy asks for, as getHeadlessConsent() does. |
defaultTranslationConfig, mergeTranslationConfigs, prepareTranslationConfig, detectBrowserLanguage | Translation helpers. |