Skip to main content

Script Integration

After publishing a cookie configuration, Consentrix generates a Cookie Script in the cookie detail page. Copy that generated <script> tag and embed it in your website to activate the banner and privacy preference panel.

This page is intended for developers and technical implementers who need to embed the Consentrix cookie widget, handle browser-side events, and work with Content Security Policy requirements.

Cookie Script section

Get the script

  1. Navigate to Platform → Cookies.
  2. Click View on a published cookie.
  3. Scroll to the Cookie Script section.
  4. Copy the generated <script> tag exactly as shown.

Embed the script

Add the generated script tag to your website's HTML. Place it either:

  • Inside the <head> tag for early loading, or
  • Just before the closing </body> tag
index.html
<!doctype html>
<html>
<head>
<!-- Other head elements -->

<!-- Cookie consent script -->
<script
src="https://cdn-consentrix.odds.team/cookie-script.js"
data-scope="YOUR_SCOPE_ID"
></script>

</head>
<body>
<!-- Page content -->
</body>
</html>

Do not hard-code a UAT or environment-specific artifact name in your application. The detail page already shows the correct script URL for the current deployment target.

data-scope attribute

The data-scope attribute links the script to the published cookie's System ID. The widget reads this value from the script tag, fetches the matching cookie consent details, and includes the same scope when saving visitor decisions. Each published cookie has its own generated value — do not modify this value manually.

Host page styling and theming

The current widget version mounts into #cookie-consent-root and renders the UI inside a Shadow DOM. This changes how host-page styling works:

  • General element selectors from your website such as button, p, or div no longer bleed into the cookie widget.
  • The widget still inherits theme variables from #cookie-consent-root.
  • Dark mode is synchronized automatically when the parent page uses .dark, data-theme="dark", or data-color-mode="dark" on <html> or <body>.

Theme overrides

Use CSS variables on #cookie-consent-root when you want to customize the widget theme, especially the primary color, border styling, or banner shadow from the host page.

theme-overrides.css
#cookie-consent-root {
--radius: 1rem;
--background: #ffffff;
--foreground: #0f172a;
--primary: #0f766e;
--primary-foreground: #ffffff;
--border: #d1d5db;
--shadow-banner: 0 10px 30px rgba(15, 23, 42, 0.18);

}

.dark #cookie-consent-root,
[data-theme="dark"] #cookie-consent-root,
[data-color-mode="dark"] #cookie-consent-root {
--background: #0f172a;
--foreground: #f8fafc;
--primary: #34d399;
--primary-foreground: #052e2b;
--border: rgba(255, 255, 255, 0.12);
}

If you want a different background in dark mode, override --background and related variables under your host page dark-theme selector as shown above.

This is also compatible with host-page theme toggling because the widget keeps listening to dark mode signals from the parent page.

Locale behavior

The widget currently supports th and en.

Auto-detection priority

Locale is resolved in this order:

  1. The host page <html lang> value, such as lang="th" or lang="en-US"
  2. URL path prefix such as /th/... or /en/...
  3. First subdomain such as th.example.com or en.example.com
  4. Browser language such as th-TH or en-US

If no supported locale is detected, the widget falls back to th.

Live locale switching

If your site is a SPA or allows in-page language switching, dispatch a browser event after your app changes locale:

switch-cookie-locale.ts
window.dispatchEvent(
new CustomEvent('cookie-consent:locale', {
detail: 'en',
})
);

The detail value may be a short code such as th or en, or a locale string such as th-TH or en-US. Unsupported values are ignored.

Object detail is also supported:

switch-cookie-locale-object.ts
window.dispatchEvent(
new CustomEvent('cookie-consent:locale', {
detail: { locale: 'en-US' },
})
);

The Consentrix cookie widget dispatches CookieScript-compatible browser CustomEvents on window after a consent action is successfully saved. Use these events from your website to update analytics tags, enable third-party scripts, or synchronize client-side state.

Event name

Canonical Event

EventDescription
consentrix_cookie_consentCanonical event for all consent decisions

Action-Specific Lightweight Events

EventDescription
consentrix_cookie_accept_allFires when user clicks "Accept All"
consentrix_cookie_reject_allFires when user clicks "Reject All"
consentrix_cookie_save_preferencesFires when user saves custom preferences
consentrix_cookie_open_preferencesFires when preferences modal opens

Category-Enabled Events (for lazy-loading scripts)

These events fire only once per page load for each enabled category:

EventFires When
consentrix_cookie_category_necessary_enabledNecessary category is enabled (always true)
consentrix_cookie_category_analytics_enabledAnalytics consent is given
consentrix_cookie_category_marketing_enabledMarketing consent is given

Single unified listener

The consentrix_cookie_consent event fires for all consent decisions. Use the action field in the event detail to distinguish between different outcomes:

cookie-consent-listener.ts
// Single listener covers all decisions
window.addEventListener('consentrix_cookie_consent', (event) => {
const { detail } = event as CustomEvent<ConsentEventDetail>;

console.log('Action:', detail.action); // 'accept_all', 'reject_all', 'save_preferences', or 'update'
console.log('Source:', detail.source); // 'banner' or 'preferences_modal'
console.log('Categories:', detail.categories); // { necessary: true, analytics: true }
console.log('Timestamp:', detail.timestamp); // ISO 8601 string

// Enable/disable scripts based on the normalized category record
if (detail.categories.analytics) {
loadAnalytics();
}
if (detail.categories.marketing) {
loadMarketing();
}
});

Google Analytics 4 integration

Send consent decisions to GA4 with the action field:

ga4-integration.ts
window.addEventListener('consentrix_cookie_consent', (event) => {
const { detail } = event as CustomEvent<ConsentEventDetail>;

gtag('event', 'cookie_consent', {
event_category: 'cookie',
event_label: detail.action,
consent_id: detail.consentId,
categories: Object.keys(detail.categories).filter((key) => detail.categories[key]).join(','),
source: detail.source
});
});

Google Tag Manager integration

Push consent decisions to the data layer:

gtm-integration.ts
window.addEventListener('consentrix_cookie_consent', (event) => {
const { detail } = event as CustomEvent<ConsentEventDetail>;

dataLayer.push({
event: 'cookieConsent',
consentAction: detail.action,
consentId: detail.consentId,
categories: detail.categories,
timestamp: detail.timestamp,
source: detail.source
});
});

Event detail

The event detail structure:

type ConsentAction = 'accept_all' | 'reject_all' | 'save_preferences' | 'update';

type ConsentEventDetail = {
version: 'v1'; // Canonical event schema version
timestamp: string; // ISO 8601 string
source: 'banner' | 'preferences_modal' | 'page_load' | string;
action: ConsentAction; // Type of consent action
consentId: string; // ID of the cookie consent configuration
systemId: string | null; // System ID linked to this consent
categories: Record<string, boolean>; // Category consent state
categoryDetails?: CookieCategoryDetail[];
metadata?: Record<string, unknown>;
};

type CookieCategoryDetail = {
id: string; // Backend category ID
type: string; // Category type (e.g. "necessary", "analytics", "marketing")
title: string; // Category title
required: boolean; // Whether this category is mandatory
};

Event options

All events are dispatched with:

  • bubbles: true — Events propagate up the DOM tree
  • composed: true — Events cross Shadow DOM boundaries
  • cancelable: false — Consent decisions are facts, not requests

Notes for implementers

  • timestamp — ISO 8601 string for category events
  • source — Distinguish between quick banner actions vs. deliberate preferences modal choices
  • categories — Query-friendly category state such as { necessary: true, analytics: true, marketing: false }
  • categoryDetails — Optional UI/debug metadata for categories
  • Category enabled events fire once per page and are intended for safe lazy loading

Category-Enabled Event Detail

Category events (consentrix_cookie_category_*_enabled) include:

type CategoryEnabledEventDetail = {
timestamp: string; // ISO 8601 formatted (e.g., "2024-01-15T10:30:00.000Z")
source: string; // 'banner', 'preferences_modal', 'page_load', etc.
consentId: string; // Consent configuration ID
systemId: string | null; // System ID
category: string; // Category type (e.g., "analytics", "marketing")
categoryId: string; // Backend category ID
};

Complete event listener example

cookie-consent-all-events.ts
// 1. Canonical event - fires for ALL consent decisions
window.addEventListener('consentrix_cookie_consent', (e) => {
const { action, categories, timestamp } = e.detail;
console.log('Consent decision:', action, categories);
});

// 2. Action-specific lightweight events
window.addEventListener('consentrix_cookie_accept_all', (e) => console.log('Accept all'));
window.addEventListener('consentrix_cookie_reject_all', (e) => console.log('Reject all'));
window.addEventListener('consentrix_cookie_save_preferences', (e) => console.log('Save preferences'));
window.addEventListener('consentrix_cookie_open_preferences', (e) => console.log('Open preferences'));

// 3. Category-enabled events (for lazy-loading scripts)
window.addEventListener('consentrix_cookie_category_necessary_enabled', (e) => {
const { timestamp, category, categoryId } = e.detail;
console.log('Necessary enabled at', timestamp, '-', { category, categoryId });
});
window.addEventListener('consentrix_cookie_category_analytics_enabled', (e) => {
const { timestamp, category, categoryId } = e.detail;
console.log('Analytics enabled at', timestamp, '-', { category, categoryId });
// loadAnalyticsScripts();
});
window.addEventListener('consentrix_cookie_category_marketing_enabled', (e) => {
const { timestamp, category, categoryId } = e.detail;
console.log('Marketing enabled at', timestamp, '-', { category, categoryId });
// loadMarketingScripts();
});

// 4. Helper for registering known category events
const listenForCategoryEnabled = (category, handler) => {
window.addEventListener(
`consentrix*cookie_category*${category}_enabled`,
handler
);
};

listenForCategoryEnabled('analytics', (e) => {
const { timestamp, category, categoryId } = e.detail;
console.log(`Category ${category} enabled at`, timestamp, { categoryId });
});

Content Security Policy (CSP)

If your website uses a Content Security Policy header, allow the Consentrix script domain in script-src and the Consentrix API host in connect-src. The widget also loads its default IBM Plex Sans Thai fonts from Google Fonts; add the font domains if your site blocks external styles or fonts.

script-src 'self' https://cdn-consentrix.odds.team;
connect-src 'self' https://<consentrix-api-host>;
style-src 'self' https://fonts.googleapis.com;
font-src 'self' https://fonts.gstatic.com;

Common issues

ProblemCauseSolution
Script does not load

CSP script-src blocks the domain

Add https://cdn-consentrix.odds.team to your script-src.

Banner does not appear after the script loads

CSP connect-src blocks the Consentrix API request for cookie details

Add the Consentrix API host used by this deployment to connect-src.

Widget font does not load

CSP style-src or font-src blocks Google Fonts

Allow https://fonts.googleapis.com in style-src and https://fonts.gstatic.com in font-src, or accept the host page fallback font.

Banner does not appear

The script URL or data-scope value does not match the published cookie

Copy the full script again from the published cookie detail page and replace the existing embed snippet.

Widget styling does not match the host page

Shadow DOM isolates the widget from your page-level element selectors

Set CSS variables on #cookie-consent-root instead of styling widget internals directly.

Widget language does not update in SPA navigationThe page locale changed without a full reload

Dispatch cookie-consent:locale after your app switches language.

Console shows CSP violationBrowser blocked a resource

Open Browser Console → Console tab and look for CSP violation errors.

How to debug

  1. Open your website in a browser.
  2. Open Developer Tools (F12 or Cmd+Option+I).
  3. Check the Console tab for CSP or network errors.
  4. Check the Network tab to verify the script loaded successfully (HTTP 200).
  5. Confirm the rendered <script> tag still contains the expected data-scope value.
Avoid unsafe-inline

Using unsafe-inline in your CSP script-src weakens security. Prefer listing the specific Consentrix script domain instead.