Quickstart
Installation
npm install c15tInitialize the Runtime
getOrCreateConsentRuntime() creates a consent client and a Zustand vanilla store in a single call. The store holds all consent state and exposes methods for checking, setting, and subscribing to consent changes.
import { getOrCreateConsentRuntime } from 'c15t';
const { consentManager, consentStore } = getOrCreateConsentRuntime({
mode: 'hosted',
backendURL: 'https://your-instance.c15t.dev',
consentCategories: ['necessary', 'measurement', 'marketing'],
});Info
Hosted mode is the recommended production setup because the backend resolves jurisdiction and translations, stores consent decisions outside the current browser, and can re-sync after temporary outages.
Warning
You can switch to mode: 'offline' for local-only storage, demos, or static previews, but that removes backend audit history, automatic jurisdiction detection, and server-side consent awareness. Review Client Modes before using offline mode in production.
Subscribe to State Changes
The store is a Zustand vanilla store. Use subscribe() for UI and general state updates, subscribeToConsentChanges() for change-only consent integrations, and getState() to read the current state:
// React to every state change
consentStore.subscribe((state) => {
console.log('Consent state:', state.consents);
console.log('Show banner?', state.activeUI === 'banner');
});
// React only to real saved preference changes
consentStore
.getState()
.subscribeToConsentChanges(({ allowedCategories, deniedCategories }) => {
analytics.syncConsent({ allowedCategories, deniedCategories });
});
// Read current state at any time
const state = consentStore.getState();
console.log('Has measurement consent:', state.has('measurement'));Check and Set Consent
const state = consentStore.getState();
// Check if a category has consent
if (state.has('measurement')) {
// Safe to load analytics
}
// Accept all categories
await state.saveConsents('all');
// Accept only necessary categories
await state.saveConsents('necessary');
// Set a specific category
state.setConsent('marketing', true);Minimal Consent Prompt
Here's a bare-bones example using the store to drive a consent prompt — no framework required:
import { getOrCreateConsentRuntime } from 'c15t';
const { consentStore } = getOrCreateConsentRuntime({
mode: 'hosted',
backendURL: 'https://your-instance.c15t.dev',
consentCategories: ['necessary', 'measurement', 'marketing'],
});
// Subscribe to show/hide the banner
consentStore.subscribe((state) => {
const banner = document.getElementById('consent-banner');
if (banner) {
banner.style.display = state.activeUI === 'banner' ? 'block' : 'none';
}
});
// Wire up buttons
document.getElementById('accept-all')?.addEventListener('click', () => {
consentStore.getState().saveConsents('all');
});
document.getElementById('reject')?.addEventListener('click', () => {
consentStore.getState().saveConsents('necessary');
});Verify It Works
Open the browser console and inspect the store state:
// The store is also available on the window object
const state = window.c15tStore?.getState();
console.log('Consents:', state?.consents);
console.log('Has consented:', state?.hasConsented());
console.log('Location:', state?.locationInfo);Info
No UI included — the c15t core package is fully headless. See Building UI for creating your own components, or use @c15t/react / @c15t/nextjs for pre-built UI.
Optional: Install Agent Skills
Install c15t agent skills to let AI agents help with styling, i18n, scripts & other configuration.
npx @c15t/cli skillsSee AI Agents for bundled package docs and agent skills.
Next Steps
- Client Modes — Choose between hosted, offline, or custom backend
- Store API — Full reference for store state and actions
- Script Loader — Gate third-party scripts behind consent
- Building UI — Create your own consent components
- AI Agents — Get bundled package docs and reusable agent skills for c15t