Consent Experiences API
This document describes the JavaScript API for Consent Experience UIs. You can use window.transcend to control UI visibility, change language, listen for visibility changes, and apply runtime customizations.
If you are on Legacy Consent UIs, most of your existing integrations will continue to work. Several methods are unchanged, but Consent Experience UIs also add new capabilities for runtime configuration and remounting. A number of Legacy Consent UIs methods have been removed — see the Removed in Consent Experience UIs section.
The API is available globally in the browser once the Consent Experience UIs script loads. In most cases you do not need to call anything to show the consent banner, see Auto-prompt vs. manual display below. Use ready() or readyQueue when you want to own when and how the UI appears or re-renders, gather UI data for e.g. metrics, or respond to banner events.
These methods work the same way as in Legacy Consent UIs. Existing integrations that call them should not require changes:
ready()/readyQueueshowConsentManager()hideConsentManager()autoShowConsentManager()setActiveLocale()/getActiveLocale()setUiVariables()addEventListener()/removeEventListener()(though there are some changes to theview-state-changeevent)
mountConsentApp()— mount or remount the UI (useful for debugging purposes when SPAs remove the UI DOM node)getVariant()— read the active Consent Experience slugsetConfig()— update UI configuration at runtime
The following methods were available on window.transcend in Legacy Consent UIs but are not part of the Consent Experience UIs API. If your site calls any of these, please update your integration before migrating.
| Method | Description in Legacy Consent UIs | Migration in Consent Experience UIs |
|---|---|---|
viewStates | Set of possible UI view states | This is equivalent to the set of Consent Experiences configured within the admin dashboard |
getViewState() | Returns the current UI view state | Use getVariant() to track the current experience shown |
getPolicies() | Returns configured privacy/cookie policy metadata | Configure policies in the Transcend dashboard; use setUiVariables() for dynamic copy |
getUiVariables() | Returns the current UI variable map | Track variable values in your own application state |
setPrivacyPolicy() / setSecondaryPolicy() | Sets the privacy policy URLs at runtime | Configurable through setting the data-links attribute on airgap.js which accepts a comma delimited URL array |
toggleConsentManager() | Toggles the consent UI open or closed | Call showConsentManager() or hideConsentManager() explicitly |
doNotSell() | Opens or triggers the "Do Not Sell" flow | Configure the equivalent experience in the Transcend dashboard for your privacy regime and call .showConsentManager({ viewState: '{do-not-sell-slug}' }) |
optOutNotice() | Opens or triggers an opt-out notice | Configure the equivalent experience in the Transcend dashboard for your privacy regime and call .showConsentManager({ viewState: '{opt-out-notice-slug}' }) |
By default, Consent Experience UIs handle banner display for you. If auto prompt is enabled for the visitor's privacy regime in your Transcend Admin Dashboard configuration, the consent banner is shown automatically on page load when appropriate, no JavaScript integration required.
Use display methods within ready() or readyQueue only when you want to own display logic yourself. In that case, disable auto prompt for the relevant regime(s) in the admin dashboard, then use the ready hooks to call e.g. showConsentManager() on your own schedule; for example, it can be called when the visitor clicks a "Privacy Settings" link.
You would still use ready() for non-display integrations (e.g. listening for view-state-change events) even when auto prompt is enabled.
In order to manually display the UI when auto prompt is disabled, wait for airgap.js (if you're loading airgap.js synchronously, you can simply put a script tag after the airgap.js script tag), then register your callback with transcend.ready():
<script src="https://transcend-cdn.com/airgap.js"></script>
<script>
window.transcend.ready((transcend) => {
// Open the consent manager when the user clicks "Privacy Settings"
document
.getElementById('privacy-settings')
?.addEventListener('click', () => transcend.showConsentManager());
});
</script>If the Consent Experience UIs script has already finished loading by the time your code runs, transcend.ready() invokes your callback immediately; there's no need to check initialization state yourself.
| Method | Description |
|---|---|
ready() | Queue a callback until the API is ready, or run immediately if already initialized |
readyQueue | Low-level queue for callbacks registered before airgap initializes |
mountConsentApp() | Mount or remount the consent UI (automatically performed on init, but may be useful for debugging SPAs) |
showConsentManager() | Open the consent banner or preferences modal |
hideConsentManager() | Close the consent UI |
autoShowConsentManager() | Open the UI only when auto-prompt rules allow it |
setActiveLocale() | Change the display locale |
getActiveLocale() | Get the current display locale |
getVariant() | Get the active Consent Experience slug |
setConfig() | Update UI configuration at runtime |
setUiVariables() | Inject dynamic values into UI copy |
addEventListener() / removeEventListener() | Listen for UI events (e.g. view-state-change) |
ready() and readyQueue are unchanged from Legacy Consent UIs. The Consent Experience UIs API becomes available in stages. Which method you use depends on how early your code runs:
| When your code runs | What to use |
|---|---|
| Before airgap has initialized | Stub window.transcend and push to readyQueue |
| After airgap, before the UI API is ready | ready() |
| After the UI API is ready | Call API methods directly, or use ready() (runs immediately) |
airgap.js loads → transcend.ready() available
↓
UI loads and mounts → full API available → queued callbacks run
↓
transcend.ready() calls your callback immediatelyUnchanged from Legacy Consent UIs. Queues a function to run once the full window.transcend API is initialized (showConsentManager, setActiveLocale, event listeners, and so on). Use this after airgap.js has initialized but whenever you need to wait for the UI API.
If initialization has already completed, your callback is invoked right away.
ready(callback: (api: TranscendUiAPI) => void): void;window.airgap.ready(() => {
window.transcend.ready((transcend) => {
transcend.addEventListener('view-state-change', (event) => {
console.log('Consent UI state:', event.detail.viewState);
});
});
});Unchanged from Legacy Consent UIs. A low-level array of callbacks that run when the API finishes initializing. In most cases you should prefer ready() instead.
Use readyQueue only when you need to queue UI logic before airgap has initialized — for example, when auto prompt is disabled and you have an inline script that runs before the airgap bundle loads. Stub out the window.transcend object and push your callback onto the queue:
readyQueue: Array<(transcend: TranscendUiAPI) => void>;// Before airgap or the Consent UI script has loaded
window.transcend = window.transcend ?? {};
window.transcend.readyQueue = window.transcend.readyQueue ?? [];
window.transcend.readyQueue.push((transcend) => {
transcend.addEventListener('view-state-change', (event) => {
console.log('Consent UI state:', event.detail.viewState);
});
});When the Consent Experience UIs script loads, any callbacks in readyQueue are preserved and executed once the API is ready. After that, use ready() for any additional callbacks.
Creates and mounts the consent UI in the page. This runs automatically when the Consent UI script loads, you normally do not need to call it yourself.
Call it again to remount the UI from scratch. This is useful when a single-page app framework (React, Vue, etc.) removes the consent UI's container from the DOM - for example during client-side navigation, route changes, or hydration mismatches. Remounting restores the banner and modal without reloading the page.
mountConsentApp(): void;When called, it:
- Removes any existing consent UI container (
#transcend-shadow-root) - Creates a fresh container and renders the UI
- Loads your theme stylesheet
- Runs
autoShowConsentManager()— which shows the banner automatically if auto prompt is enabled for the visitor's regime
// Remount after the consent UI was removed from the DOM
window.transcend.mountConsentApp();Example — remount when a React root replaces page content
// After React re-renders and removes transcend's container from the DOM
function ensureConsentUiMounted() {
if (!document.getElementById('transcend-shadow-root')) {
window.transcend.mountConsentApp();
}
}
// Call after navigation or when you detect the UI is missing
ensureConsentUiMounted();Remounting rebuilds the UI but does not reset consent state. The visitor's choices remain available via
window.airgap.getConsent().
These methods are unchanged from Legacy Consent UIs.
The Consent Manager has up to three layers, depending on your configuration:
- Banner — the first-layer notice shown at the bottom or top of the page
- Modal — the full preferences panel where users manage purposes
- Trackers — the cookie or vendor detail view opened from the modal
Opens the consent UI for the visitor. Displays the banner or modal based on your active UI variant.
showConsentManager(options?: { viewState?: string }): void;| Option | Type | Description |
|---|---|---|
viewState | string (optional) | Consent Experience slug to use when opening (e.g. "banner-into-modal"). Must match an experience configured in your Transcend dashboard. If omitted, the default experience for the visitor's privacy regime is used. |
// Open with the default variant for this visitor
window.transcend.showConsentManager();
// Open a specific UI variant
window.transcend.showConsentManager({ viewState: 'banner-into-modal' });Closes the consent UI, regardless of which layer is currently visible. Fires a view-state-change event with viewState: 'Closed'.
hideConsentManager(): void;window.transcend.hideConsentManager();Runs the same display logic Transcend uses on page load when auto prompt is enabled in the admin dashboard for the visitor's privacy regime. You rarely need to call this yourself since it is invoked automatically during initialization unless you have taken over display logic.
The UI is shown if any of the following are true:
- Auto prompt is enabled for the visitor's regime in the admin dashboard, and the user has not confirmed consent
- Prompting is forced on via config (
prompt: "true"or"on")
If the visitor has already confirmed consent, this method does nothing.
autoShowConsentManager(options?: { viewState?: string }): void;Accepts the same viewState option as showConsentManager().
window.transcend.autoShowConsentManager();These methods are unchanged from Legacy Consent UIs.
Changes the language displayed in the consent UI and reloads the corresponding translations.
setActiveLocale(locale: LocaleValue): void;LocaleValue is a BCP 47 locale tag. Common values include 'en', 'fr-FR', 'de-DE', 'es-ES', 'pt-BR', and 'ja-JP'. The locale must be enabled for your active experience within the Consent Experience Editor.
window.transcend.setActiveLocale('fr-FR');You can call this to keep the consent UI in sync with a language picker on your site:
siteLanguagePicker.addEventListener('change', (event) => {
window.transcend.setActiveLocale(event.target.value);
});Returns the locale currently displayed in the consent UI.
getActiveLocale(): LocaleValue;const locale = window.transcend.getActiveLocale();
// e.g. "en", "fr-FR"Returns the ID of the Experience currently in use (e.g. "banner-into-modal", "modal-only"). Experiences are configured in the Transcend dashboard and mapped to privacy regimes.
getVariant(): string | undefined;const variant = window.transcend.getVariant();Updates Consent UI settings at runtime without reloading the page. Provided values are merged into the active configuration.
setConfig(config: Partial<LoadOptions>): void;Some common uses include:
// Change which Experience is shown for a privacy regime
window.transcend.setConfig({
regimeVariantMap: {
GDPR: 'modal-only',
CPRA: 'banner-into-modal',
},
});
// Opens the shadow root the UI is shown in
window.transcend.setConfig({
shadowRoot: 'open',
});Unchanged from Legacy Consent UIs.
Replaces placeholder variables in consent UI copy with dynamic values from your site — for example, your company name or a link to your privacy policy.
setUiVariables(variables: Record<string, string>): Promise<void>;await window.transcend.setUiVariables({
companyName: 'Acme Corp',
privacyPolicyUrl: 'https://example.com/privacy',
});Variable names must match the placeholders defined in your Transcend message templates.
You can pass configuration to the Consent UI via data-* attributes on the script tag that loads it. Attribute names use kebab-case and are converted automatically (e.g. data-ui-z-index sets the UI stacking order).
<script
src="https://transcend-cdn.com/consent-ui-v2.js"
data-ui-z-index="9999"
data-prompt="true"
></script>window.transcend supports standard DOM event listener methods. These are unchanged from Legacy Consent UIs.
addEventListener(type: 'view-state-change', listener: EventListener): void;
removeEventListener(type: 'view-state-change', listener: EventListener): void;Register listeners with ready() to ensure the API is available:
window.transcend.ready((transcend) => {
transcend.addEventListener('view-state-change', handleViewStateChange);
});Fired whenever the consent UI opens, closes, or navigates between layers. The event itself existed in Legacy Consent UIs; Consent Experience UIs changes the set of view states that are returned.
Event detail:
{
viewState: 'Banner' | 'Modal' | 'Trackers' | 'Closed';
previousViewState: 'Banner' | 'Modal' | 'Trackers' | 'Closed' | null;
}viewState | Description |
|---|---|
'Banner' | The first-layer banner is visible |
'Modal' | The preferences modal is visible |
'Trackers' | The cookie or vendor detail view is visible (Consent Experience UIs) |
'Closed' | All consent UI layers are hidden |
Listen for open and close:
window.transcend.addEventListener('view-state-change', (event) => {
const { viewState, previousViewState } = event.detail;
if (viewState === 'Closed') {
console.log(`Consent UI closed (was: ${previousViewState})`);
} else {
console.log(`Consent UI opened: ${viewState}`);
}
});Run logic when the visitor closes the preferences modal:
window.transcend.addEventListener('view-state-change', (event) => {
const { viewState, previousViewState } = event.detail;
if (viewState === 'Closed' && previousViewState === 'Modal') {
// Visitor dismissed the preferences modal
}
});