JavaScript SDK
Reference to the SDK banner cookie platform, which covers script tags, thematic and headless installation modes, API appearance, language detection and events.
@probo/cookie-banner SDK is a lightweight, non-dependent JavaScript library built on Web Components. They render the consent UI, manage the visitor’s consent status, communicate with the API platform, and enable third-party resources based on consent.
There are three ways to use the SDK, depending on your needs:
Script Tag (No Bundler)
Section entitled “Script Tag (No Bundler)”Add a single tag <script> to HTML – no building tools are required:
<script src="https://unpkg.com/@probo/cookie-banner/dist/cookie-banner.iife.js" data-banner-id="YOUR_BANNER_ID" data-base-url="https://your-probo-instance.com/api/cookie-banner/v1/" data-position="bottom-left"></script>
<!-- Required: reopen control in the header or footer --><probo-settings-link>Cookie settings</probo-settings-link>This automatically generates a fully stylized consent dialog. Place <probo-settings-link> in the header or footer so that visitors can reopen their preferences — see Settings link.
| Attribute | Required | Description |
|---|---|---|
data-banner-id |
Yes | Your banner ID on the platform console |
data-base-url |
Yes | Cookie banner of the platform URL base |
data-position |
No | Card position: bottom-left (default), bottom-right, bottom-center, top-left, top-right, or top-center |
data-lang |
No | Forcing a specific language (e.g. "fr"). When it is omitted, the SDK automatically detects from the page or browser. Language Detection. |
Themed Banner (ES Module)
Section entitled “Themed Banner (ES Module)”For grouped applications (React, Vue, Svelte, Next.js, etc.), import the thematic banner as ES mode:
npm install @probo/cookie-bannerRegister the component and place it in HTML or template:
import { registerCookieBanner } from "@probo/cookie-banner";
registerCookieBanner();<probo-cookie-banner banner-id="YOUR_BANNER_ID" base-url="https://your-probo-instance.com/api/cookie-banner/v1/" position="bottom-left"></probo-cookie-banner>
<!-- Required: reopen control in the header or footer --><probo-settings-link>Cookie settings</probo-settings-link>| Attribute | Required | Description |
|---|---|---|
banner-id |
Yes | Your banner ID on the platform console |
base-url |
Yes | Cookie banner of the platform URL base |
position |
No | Card position: bottom-left (default), bottom-right, bottom-center, top-left, top-right, or top-center |
lang |
No | Forcing a specific language (e.g. "fr"). When it is omitted, the SDK automatically detects from the page or browser. Language Detection. |
Because this is a Web component, it works in any framework. In React, JSX treats it as a custom item. In Vue or Svelte, use it directly in the template. React Integration A complete step guide with a useConsent hook, Next.js setting and TypeScript statements.
See Theming for how to customize colors, fonts and style.
For programmatic access to consent status from any module (not just DOM), see Consent Manager API.
Headless Components (Full Control)
“Headless Components (Full Control)”For full control over your consent UI, use the headless components.These are building blocks of unstylized Web components that you compose and stylize yourself:
import { registerHeadlessComponents } from "@probo/cookie-banner/headless";
registerHeadlessComponents();Then build your own layout:
<probo-cookie-banner-root banner-id="YOUR_BANNER_ID" base-url="BASE_URL"> <probo-banner> <div class="my-banner"> <p data-text="banner_description">We use cookies to improve your experience.</p> <!-- Opt-in / opt-out primary actions --> <probo-accept-button> <button>Accept all</button> </probo-accept-button> <probo-reject-button> <button>Reject all</button> </probo-reject-button> <probo-customize-button> <button>Customize</button> </probo-customize-button> <!-- Notice presentation (APPI, Mexico, unregulated): single dismiss --> <probo-acknowledge-button> <button>Got it</button> </probo-acknowledge-button> </div> </probo-banner>
<probo-preference-panel> <div class="my-preferences"> <probo-category-list> <template> <div class="category"> <span data-slot="name"></span> <span data-slot="description"></span> <probo-category-toggle> <input type="checkbox" /> </probo-category-toggle> </div> <probo-cookie-list> <template> <div class="cookie"> <span data-slot="name"></span> <span data-slot="type"></span> <span data-slot="duration"></span> </div> </template> </probo-cookie-list> </template> </probo-category-list> <probo-save-button> <button>Save preferences</button> </probo-save-button> </div> </probo-preference-panel>
<!-- CCPA only: shown when state is privacy_choices --> <probo-privacy-choices> <div class="my-privacy-choices"> <probo-reject-button> <button>Do Not Sell or Share My Personal Information</button> </probo-reject-button> </div> </probo-privacy-choices></probo-cookie-banner-root>
<!-- Required outside the root (header or footer) --><probo-settings-link>Cookie settings</probo-settings-link>Use resolveLayout / resolveBannerText display the appropriate buttons and copy for active presentation (OPT_IN, OPT_OUT, or NOTICE).
Component Reference
Section entitled ‘Component Reference’| Component | Description |
|---|---|
<probo-cookie-banner-root> |
The root element. requires banner-id and base-url. The optional attribute lang to force a language. Manages the client’s life cycle and status. |
<probo-banner> |
Visibility follows layout.initial_state (for example, closed under CCPA – see Settings link). |
<probo-accept-button> |
Wrap a button that records the consent ___ZBT_I18N_RUNTIME_BLOCK_216__. |
<probo-reject-button> |
Wrap a button that records consent REJECT_ALL (opt-out / Do not sell). |
<probo-customize-button> |
Wrap a button that opens the Preferences panel. |
<probo-acknowledge-button> |
Wrap a button that records ___ZBT_I18N_RUNTIME_BLOCK_221__ for NOTICE Presentations (informative deactivation). Do not reuse all-accept for this. |
<probo-preference-panel> |
Container for per-category consent toggles. |
<probo-privacy-choices> |
Surface CCPA privacy options (opt-out sale/sharing + declaration of sensitive PI rights). It is displayed when the state is privacy_choices. |
<probo-category-list> |
Render a <template> once per cookie category. Complete data-slot="name" and data-slot="description". |
<probo-category-toggle> |
Connects the checkbox inside it to the category consent state. |
<probo-cookie-list> |
Make a <template> once per cookie in category. Complete data-slot="name", data-slot="type" and data-slot="duration". |
<probo-save-button> |
Wrap a button that saves the current project preferences. |
<probo-settings-link> |
Required the header/footer re-opening control. The click target comes from layout.reopen_state. See Settings link. |
Layout API
Section entitled “LayoutAPI”Starting with 0.12,APIreturns a structure layout on the banner configuration. Headless integrators should read it instead of branching on regulation or consent_mode:
import { resolveLayout, resolveBannerText,} from "@probo/cookie-banner"; // or "@probo/cookie-banner/headless"
document.addEventListener("probo-ready", (e) => { const { config } = e.detail; const layout = resolveLayout(config); // layout.presentation: "OPT_IN" | "OPT_OUT" | "NOTICE" // layout.initial_state / layout.reopen_state: "banner" | "panel" | "privacy_choices" | "hidden" // layout.buttons: which actions to show // layout.settings_link: "default" | "ccpa_privacy_choices"
const copy = resolveBannerText(config); // copy.title, copy.description, copy.primaryButton, copy.secondaryButton?});If layout is missing, the SDK detects an error and returns to the strict option - which means that the platform backend is older than probod v0.246.0Update the probod when you see this warning.
Settings link
Section titled “Settings link”<probo-settings-link> is the only re-opening control. Place it in the header or footer of your site for each embedded (script tag, theme or without head). If it is missing, the SDK issues a soft warning probo-validation - without it visitors cannot re-open their preferences.
<style> /* Style the host — typography still applies after CCPA replaces the children */ probo-settings-link { font-size: 14px; color: #334155; text-decoration: underline; }</style>
<footer> <probo-settings-link>Cookie settings</probo-settings-link></footer>Behavior by presentation / regulation (justified by layout):
| Presentation | Typical regulations | Label shown | Banner on first visit | Click opens |
|---|---|---|---|---|
| OPT_OUT (CCPA) | CCPA / CPRA | Always replaced by law. “Your Privacy Options” text and official opt-out icon (English; not translated) | Closed by default | Privacy Choices panel (privacy_choices) |
| OPT_OUT (other) | PIPEDA, LGPD | Your children (e.g. “Cookie Settings”) or a localized feedback if it is empty | Closed by default | Compact opt-out banner |
| OPT_IN | GDPR, UK GDPR, FADP, … | Your kids, or a localized drop if it’s empty | Open until the visitor chooses | Preference panel |
| NOTICE | APPI, LFPDPPP, unregulated countries | Your kids, or a localized drop if it’s empty | Open (informational dismiss) | Notice banner again |
When a opt-out signal has been applied to Global Privacy Control (GPC), the settings link may display a small GPC honored Locks next to the label.
Thematic embedding mount <probo-privacy-choices> for exclusion options, but Reappearance on this surface is CCPA-only (layout.reopen_state = privacy_choices). Other exclusion modes reopen the compact banner. Headless integrators should include <probo-privacy-choices> when they support CCPA. The Settings link automatically finds the banner root for all three integration methods.
The style probo-settings-link itself for font size and color – no internal copies. Under CCPA, the SDK replaces children, but host styles still apply. The icon retains its blue/white colors and scales with 1em.
Language Detection
Section “Language Detection”The SDK automatically resolves the visitor’s language using the following priority:
- Explicit attribute — The ___ZBT_I18N_RUNTIME_BLOCK_257__ attribute per component (or ___ZBT_I18N_RUNTIME_BLOCK_258__ on the script label)
- Page language — The ___ZBT_I18N_RUNTIME_BLOCK_259__ attribute on the element ___ZBT_I18N_RUNTIME_BLOCK_260__ using the subtag of the basic language (e.g.
frfromfr-FR) - Browser language —
navigator.languageof the browser, using the basic subtag - Default language — Default banner language configured in the console (default to
en)
The solved language is sent toAPIwhen the banner configuration is collected.APIreturns all UI text, category names and descriptions in the solved language.If there is no translation for that language,APIreturns to the default banner language.
Built-in Languages
Posts Tagged ‘built-in languages’The new banners include translations for these languages:
| Code | Language | Code | Language |
|---|---|---|---|
en |
English | nl |
Dutch |
de |
German | pl |
Polish |
es |
Spanish | pt |
Portuguese |
fr |
French | tr |
Turkish |
id |
Indonesian | uk |
Ukrainian |
it |
Italian | zh |
Chinese |
ja |
Japanese | ||
ko |
Korean |
You can customize these translations and add new languages from the platform console.
- Title and description of the banner (including exclusion and notification options)
- button tags (accept all, reject all, customize, save, reject/recognize)
- Preference panel title and description
- Cookie detail labels (type, description, duration)
- ARIA accessibility labels
- Privacy policy / cookie policy link text
- Content location text (showed when resources are blocked)
- Duration labels (years, months, days, persistent, etc.)
Forcing a Language
Section “Forcing a Language”To opt out of self-detection, set the language explicitly:
Script tag:
<script src="https://unpkg.com/@probo/cookie-banner/dist/cookie-banner.iife.js" data-banner-id="YOUR_BANNER_ID" data-base-url="https://your-probo-instance.com/api/cookie-banner/v1/" data-lang="de"></script>Themed banner:
<probo-cookie-banner banner-id="YOUR_BANNER_ID" base-url="https://your-probo-instance.com/api/cookie-banner/v1/" lang="de"></probo-cookie-banner>Headless components:
<probo-cookie-banner-root banner-id="YOUR_BANNER_ID" base-url="https://your-probo-instance.com/api/cookie-banner/v1/" lang="de"> <!-- ... --></probo-cookie-banner-root>Matching the Page Language
Section “Matching the Page Language”If your page has an attribute lang on the item ___ZBT_I18N_RUNTIME_BLOCK_287__, the SDK automatically selects it:
<html lang="fr"></html>This is the recommended approach for multilingual sites that have already set the lang attribute as part of their i18n setting.
The SDK releases custom events that bubble through the DOM. Listen to the root element or any ancestor:
| Event | Detail | Description |
|---|---|---|
probo-ready |
{ config, gpcApplied, regulation } |
Where it is necessary to comply with the requirements of national data protection legislation, it must be provided that, where necessary, it is necessary to comply with the requirements of national data protection legislation. default_language, texts, cookie_policy_url, cookie_policy_url, gpcApplied, _ |
probo-state |
{ state, prev } |
Starea: loading, banner, panel, privacy_choices, hidden. |
probo-consent |
{ action, consent_data } |
Actions: ACCEPT_ALL, REJECT_ALL, CUSTOMIZE, GPC, ACKNOWLEDGE. |
probo-validation |
{ missing } |
Soft composition warning (e.g. missing <probo-settings-link>). Does not block load. |
document.addEventListener("probo-consent", (e) => { console.log("Consent action:", e.detail.action);});How consent is stored
Section entitled “How Consent Is Stored”- Client-side: A cookie
probo_consentstores the state of consent of the visitor. The cookiemax-ageis set at the expiration of the consent set on the banner (in days). It usesSameSite=Lax. - Server-side: Each consent action is recorded through the API platform with banner version, visitor ID, type of action, anonymized IP address and user agent. IP addresses are anonymized before storage (IPv4 last zero octet, IPv6 masked at /48) – full IP never persists. Audit Trail for the complete list of stored fields.
- Visitor identity: The SDK generates a random visitor ID and stores it in
localStorage. This ID is used to search for existing consent when the visitor returns. - Offline resilience: If API is inaccessible when the consent is registered, the request is ran into
localStorageand automatically withdrawn on the next page loading.
Integrations
Section entitled ‘Integrations’SDKs come with built-in integrations that automatically synchronize consent status with third-party services. Integrations are enabled by default – they are only enabled when the corresponding flags are configured on the cookie categories in the platform console.
Google Consent Mode
The “Google Consent Mode” sectionThe SDK pushes Google Consent Mode v2 signals to gtag() or dataLayer, keeping Google tags in sync with the visitor's consent.
How it works:
- When uploaded, the SDK sends a call
consent("default", ...)that sets all types of consent configured to"denied". - When the visitor makes a choice, the SDK sends a call
consent("update", ...)with"granted"or"denied"for each type of consent based on the visitor's choices by category.
The configuration is driven by GCM consent types Map categories to Google consent types, such as analytics_storage, ad_storage, ad_user_data, or ad_personalization. Categories without GCM consent types are ignored.
The integration automatically detects window.gtag or window.dataLayer.
PostHog
Section entitled ‘PostHog’PostHog is not automatically synchronized by the SDK – but Consent Manager API It gives you everything you need to log in a few rows and comply with the GDPR, CCPA and other regulations that the banner manages.
See the dedicated guides:
- How to Set Up PostHog:GDPR, CCPA and Global Privacy Laws — setting no cookies vs. conscious consent, with a minimum example of work for each.
- PostHog feature flags behind a cookie banner — to evaluate the flags only after analytical consent and
identify()and why Track 2 should always usecookieless_mode: "on_reject".
Full integration of operation (including a demonstration of the flag of the feature with consent is cookie-banner-react example.