Store API Overview
Entry Points
getOrCreateConsentRuntime(options)
The recommended entry point. Creates both a consent client and a Zustand vanilla store in one call, with built-in caching — calling it again with the same options returns the same instance.
import { getOrCreateConsentRuntime } from 'c15t';
const { consentManager, consentStore, cacheKey } = getOrCreateConsentRuntime({
mode: 'hosted',
backendURL: 'https://your-instance.c15t.dev',
consentCategories: ['necessary', 'measurement', 'marketing'],
scripts: [
{ id: 'analytics', src: 'https://cdn.example.com/analytics.js', category: 'measurement' },
],
callbacks: {
onConsentChanged: ({ allowedCategories, deniedCategories }) => {
console.log('Allowed:', allowedCategories);
console.log('Denied:', deniedCategories);
},
},
debug: true,
});Returns: { consentManager, consentStore, cacheKey }
consentManager— The low-level client instanceconsentStore— Zustand vanilla store with all state and actionscacheKey— Cache key for this runtime instance
configureConsentManager(options)
Lower-level API that creates only the client (no store). Use this when you need full control over store creation.
import { configureConsentManager, createConsentManagerStore } from 'c15t';
const manager = configureConsentManager({
mode: 'hosted',
backendURL: 'https://your-instance.c15t.dev',
});
const store = createConsentManagerStore(manager, {
initialConsentCategories: ['necessary', 'measurement'],
scripts: [{ id: 'analytics', src: '...', category: 'measurement' }],
callbacks: {
onConsentChanged: ({ allowedCategories }) => console.log(allowedCategories),
},
});createConsentManagerStore(manager, options)
Creates a Zustand vanilla store from a client instance. Accepts all store configuration options.
import { createConsentManagerStore } from 'c15t';
const store = createConsentManagerStore(manager, {
initialConsentCategories: ['necessary', 'measurement', 'marketing'],
debug: true,
reloadOnConsentRevoked: true,
});Legal Links
Configure legal policy URLs in store options via legalLinks:
const { consentStore } = getOrCreateConsentRuntime({
mode: 'offline',
legalLinks: {
privacyPolicy: {
href: '/privacy',
target: '_self',
},
cookiePolicy: {
href: '/cookies',
target: '_self',
},
termsOfService: {
href: 'https://example.com/terms',
target: '_blank',
rel: 'noopener noreferrer',
label: 'Terms of Service',
},
},
});Notes:
- Omitting a key (for example
termsOfService) hides that link. labeloverrides the translated text for that single link.- Use
_selffor internal pages and_blank+rel="noopener noreferrer"for external pages. - The
c15tpackage is headless; these links are used by your UI layer (custom UI or@c15t/ui-based integrations).
Overrides
Set initial overrides to force location/language signals during runtime initialization:
const { consentStore } = getOrCreateConsentRuntime({
mode: 'offline',
overrides: {
country: 'DE',
region: 'BY',
language: 'de-DE',
},
});You can also force Global Privacy Control behavior for testing:
const { consentStore } = getOrCreateConsentRuntime({
mode: 'offline',
overrides: {
gpc: true,
},
});For runtime updates after initialization, call setOverrides().
Warning
Treat overrides as an environment/testing tool. Avoid hard-coding production overrides unless that behavior is intentional for your deployment.
Store Patterns
Reading State
const state = consentStore.getState();
// Consent state
state.consents // { necessary: true, measurement: false, ... }
state.has('measurement') // false
state.hasConsented() // false (no consent given yet)
state.model // 'opt-in' | 'opt-out' | 'iab' | null
// UI state
state.activeUI // 'banner' | 'dialog' | 'none'
state.consentTypes // [{ name: 'necessary', ... }, ...]
// Location and info
state.locationInfo // { countryCode: 'DE', regionCode: 'BY' }
state.hasFetchedBanner // true (init complete)Subscribing to Changes
Use subscribe() for UI state and other broad store updates:
// Subscribe to all state changes
const unsubscribe = consentStore.subscribe((state, prevState) => {
console.log('State changed:', state);
});
// React to specific changes by comparing with previous state
consentStore.subscribe((state, prevState) => {
if (state.activeUI !== prevState.activeUI) {
console.log('Visible UI changed:', state.activeUI);
}
});
// Unsubscribe when done
unsubscribe();Use subscribeToConsentChanges() when you only want real saved preference changes:
const unsubscribeConsentChanges = consentStore
.getState()
.subscribeToConsentChanges(({ allowedCategories, deniedCategories }) => {
analytics.syncConsent({ allowedCategories, deniedCategories });
});
unsubscribeConsentChanges();Info
Prefer subscribeToConsentChanges() or onConsentChanged for analytics SDKs and consent-mode integrations. Raw consentStore.subscribe() fires for every store update, including UI-only changes.
Window Namespace
The store is also exposed on the window object for debugging and direct access:
// Access from anywhere (e.g., browser console)
const state = window.c15tStore?.getState();
console.log(state?.consents);The namespace defaults to c15tStore and can be configured via the namespace store option.
Options Reference
Warning: ExtractedTypeTable: Could not extract "ConsentRuntimeOptions" from "./packages/core/src/runtime/index.ts" using base path "/vercel/path0/apps/c15t-docs/.leadtype/c15t". Verify the path/name and that the file is included by your tsconfig.