JavaScript API
Complete API reference for the ConsentStack JavaScript SDK.
Once the ConsentStack script loads, the full API is available at window.consentstack. Use it to read consent state, set consent programmatically, listen for changes, and control the banner and preferences UI.
TypeScript types
The key types you will work with:
// Consent state: a map of category ID to granted/denied
type ConsentCategories = Record<string, boolean>
// Example: { essential: true, analytics: false, marketing: false }
// SDK event names
type ConsentEventType =
| "ready"
| "consent"
| "error"
| "preferences:open"
| "preferences:close"
// Event payloads
type ConsentEventData = {
ready: { config: ConsentConfig | null; consent: Record<string, boolean> | null }
consent: Record<string, boolean>
error: Error
"preferences:open": undefined
"preferences:close": undefined
}
// Full config object (returned by getConfig)
interface ConsentConfig {
appearance: Appearance
content: Content
categories: ConsentCategory[]
showReentryButton: boolean
}Consent operations
These methods let you read and write consent state directly.
getConsent()
Returns the visitor's current consent choices, or null if they have not made a decision yet.
getConsent(): Record<string, boolean> | nullconst consent = window.consentstack.getConsent()
if (consent) {
console.log("Analytics allowed:", consent.analytics)
} else {
console.log("No consent decision yet")
}setConsent()
Sets consent programmatically. This saves the decision to local storage, logs it to the ConsentStack server, activates or blocks scripts accordingly, and hides the banner.
setConsent(categories: Record<string, boolean>): Promise<void>| Parameter | Type | Description |
|---|---|---|
categories | Record<string, boolean> | A map of category IDs to true (granted) or false (denied). |
// Grant analytics, deny marketing
await window.consentstack.setConsent({
essential: true,
analytics: true,
marketing: false,
})If this is the visitor's first consent decision, it is logged as an initial event. Subsequent calls are logged as update events. If you revoke a previously granted category, the SDK shows a refresh prompt since already-executed scripts cannot be undone.
hasConsent()
Checks whether a specific category is currently granted. Returns false if the visitor has not made a decision yet.
hasConsent(category: string): booleanif (window.consentstack.hasConsent("analytics")) {
loadCustomAnalytics()
}onConsentChange()
Subscribes to consent changes. Your callback fires every time consent is set or updated, whether from the banner, preferences panel, or a setConsent() call. Returns an unsubscribe function.
onConsentChange(
callback: (consent: Record<string, boolean>) => void
): () => voidconst unsubscribe = window.consentstack.onConsentChange((consent) => {
if (consent.analytics) {
initAnalytics()
}
})
// Later, stop listening
unsubscribe()UI operations
Control the consent banner and preferences panel from your own code.
showBanner()
Displays the consent banner. In the default banner mode, the SDK shows the banner automatically for new visitors. Use this method to re-show it manually, for example, in headless mode where you handle the UI trigger yourself.
showBanner(): voiddocument.getElementById("manage-cookies").addEventListener("click", () => {
window.consentstack.showBanner()
})showPreferences()
Opens the preferences panel where visitors can toggle individual consent categories.
showPreferences(): void// Open preferences from a footer link
document.getElementById("cookie-settings").addEventListener("click", () => {
window.consentstack.showPreferences()
})You can also open preferences by navigating to #cs-preferences. The SDK listens for this hash automatically.
hidePreferences()
Closes the preferences panel programmatically. Emits a preferences:close event and re-shows the re-entry button if the visitor has already made a consent decision.
hidePreferences(): voidisPreferencesOpen()
Returns whether the preferences panel is currently visible.
isPreferencesOpen(): booleanif (!window.consentstack.isPreferencesOpen()) {
window.consentstack.showPreferences()
}Events
Subscribe to SDK lifecycle events for fine-grained control over your integration.
on()
Subscribes to a named SDK event. Returns an unsubscribe function.
on<T extends ConsentEventType>(
event: T,
callback: (data: ConsentEventData[T]) => void
): () => void| Event | Payload | Fires when |
|---|---|---|
"ready" | { config, consent } | SDK has initialized and config is loaded. |
"consent" | Record<string, boolean> | Consent state changes (same as onConsentChange). |
"error" | Error | An SDK error occurs. |
"preferences:open" | undefined | Preferences panel opens. |
"preferences:close" | undefined | Preferences panel closes. |
// Wait for the SDK to be ready before reading state
const unsubscribe = window.consentstack.on("ready", ({ config, consent }) => {
console.log("SDK ready. Region categories:", config?.categories)
console.log("Current consent:", consent)
unsubscribe()
})
// Track when users open preferences
window.consentstack.on("preferences:open", () => {
analytics.track("consent_preferences_opened")
})Configuration
getConfig()
Returns the loaded consent configuration object, or null if the SDK has not finished initializing. The config includes appearance settings, content strings, category definitions, and re-entry button settings.
getConfig(): ConsentConfig | nullconst config = window.consentstack.getConfig()
if (config) {
console.log("Categories:", config.categories.map(c => c.name))
console.log("Layout:", config.appearance.layout)
}getRegion()
Returns the resolved region string for the current visitor (e.g. "US-CA", "gdpr"), or null if not yet resolved.
getRegion(): string | nullconst region = window.consentstack.getRegion()
if (region === "US-CA") {
// Show the California-specific privacy choices link
}Source: packages/sdk/src/types.ts:397. Wired through core.getRegion() at packages/sdk/src/index.ts:182.
getGeo()
Returns a GeoDetails object with city, postal code, latitude, longitude, region (e.g. US state code), timezone, and continent, or null if geo-detail is not enabled or available. Each field is string | null.
getGeo(): GeoDetails | nullconst geo = window.consentstack.getGeo()
if (geo?.region === "CA") {
// Likely California (when the resolved region is also US)
}The method is declared at packages/sdk/src/types.ts:400; the GeoDetails shape is at packages/sdk/src/types.ts:184-192. Geo-detail availability is gated by plan. Wired at packages/sdk/src/index.ts:183.
clearCache()
Clears the local config cache and re-fetches the config from origin, bypassing the edge cache. Returns a Promise<void>.
clearCache(): Promise<void>await window.consentstack.clearCache()This is a developer tool. It is logged in ?cs-debug=true output. Implementation at packages/sdk/src/core.ts:1378-1411.
debug()
Prints SDK state to the browser console: site key, mode, current consent, and config version. Pass { verbose: true } to include the full config and state objects.
debug(options?: { verbose?: boolean }): void// Quick overview
window.consentstack.debug()
// Full state dump
window.consentstack.debug({ verbose: true })Debug query parameter
Add ?cs-debug=true (or ?cs-debug=1) to any page URL to enable the init waterfall, a console-printed timing breakdown of every SDK initialization phase:
Example output:
[ConsentStack] Init waterfall — ~XXms total
Config fetch ~Xms ██████████████████ (fresh)
Inject styles ~Xms █
Consent reconciliation ~Xms █ (none)
Platform adapters ~Xms █
Script blocker ~Xms █ (N rules)
Banner/UI ~Xms █ (banner shown)This is useful for diagnosing slow init times or verifying that config caching is working. No code changes required; just append the parameter to your URL.
Command queue
Before consent-core.js finishes loading, window.consentstack is an array. Push commands as tuples; the SDK replays them in order once initialized.
window.consentstack = window.consentstack || []
window.consentstack.push(["on", "ready", (data) => {
console.log("Consent ready:", data.consent)
}])
window.consentstack.push(["setConsent", { analytics: true }])Each pushed call is a tuple of [methodName, ...args]. The queue type is ConsentStackQueuedCall = [keyof ConsentStackAPI, ...unknown[]] (packages/sdk/src/types.ts:534). After the core loads, window.consentstack is replaced with the live API object (packages/sdk/src/index.ts:38-62).
Waiting for the SDK
The SDK initializes asynchronously. If your code runs before the script has loaded, window.consentstack will be undefined. Use the ready event or a guard check:
// Option 1: Guard check
if (window.consentstack) {
const consent = window.consentstack.getConsent()
}
// Option 2: Wait for ready event
function onSdkReady() {
window.consentstack.on("ready", ({ consent }) => {
console.log("Consent state:", consent)
})
}
if (window.consentstack) {
onSdkReady()
} else {
// Poll until available
const interval = setInterval(() => {
if (window.consentstack) {
clearInterval(interval)
onSdkReady()
}
}, 50)
}What's next
- Automatic script blocking: how the SDK manages third-party scripts based on consent state
- Consent models: understand opt-in, opt-out, notice, and notice-required behavior
- Quickstart: add ConsentStack to your site in under 5 minutes