JavaScript SDK
The @probo/cookie-banner SDK is a lightweight, dependency-free JavaScript library built on Web Components. It renders the consent UI, manages visitor consent state, communicates with the Probo API, and activates third-party resources based on consent.
There are three ways to use the SDK, depending on your needs:
Script Tag (No Bundler)
Section titled “Script Tag (No Bundler)”The simplest option. Add a single <script> tag to your HTML — no build tools 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>This automatically renders a fully styled consent dialog and a floating settings button. The banner appears on DOMContentLoaded if the visitor hasn’t consented yet.
| Attribute | Required | Description |
|---|---|---|
data-banner-id | Yes | Your banner ID from the Probo console |
data-base-url | Yes | The Probo cookie banner API base URL |
data-position | No | Settings button position: bottom-left (default) or bottom-right |
data-lang | No | Force a specific language (e.g. "fr"). When omitted, the SDK auto-detects from the page or browser. See Language Detection. |
data-reopen-widget | No | Set to "custom" to hide the floating settings button and use your own re-open trigger |
Themed Banner (ES Module)
Section titled “Themed Banner (ES Module)”For bundled applications (React, Vue, Svelte, Next.js, etc.), import the themed banner as an ES module:
npm install @probo/cookie-bannerRegister the component and place it in your HTML or template:
import { registerThemedBanner } from "@probo/cookie-banner";
registerThemedBanner();<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>| Attribute | Required | Description |
|---|---|---|
banner-id | Yes | Your banner ID from the Probo console |
base-url | Yes | The Probo cookie banner API base URL |
position | No | Settings button position: bottom-left (default) or bottom-right |
lang | No | Force a specific language (e.g. "fr"). When omitted, the SDK auto-detects from the page or browser. See Language Detection. |
reopen-widget | No | Set to "custom" to hide the floating settings button and use your own re-open trigger |
Since this is a Web Component, it works in any framework. In React, JSX treats it as a custom element. In Vue or Svelte, use it directly in your template.
See Theming for how to customize colors, fonts, and styling.
Headless Components (Full Control)
Section titled “Headless Components (Full Control)”For complete control over the consent UI, use the headless components. These are unstyled Web Component building blocks that you compose and style yourself:
import { registerComponents } from "@probo/cookie-banner/headless";
registerComponents();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>We use cookies to improve your experience.</p> <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> </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="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>
<probo-settings-button position="bottom-left"></probo-settings-button></probo-cookie-banner-root>Component Reference
Section titled “Component Reference”| Component | Description |
|---|---|
<probo-cookie-banner-root> | Root element. Requires banner-id and base-url. Optional lang attribute to force a language. Optional reopen-widget attribute ("floating" default or "custom"). Manages client lifecycle and state. |
<probo-banner> | Container shown when consent has not been given yet. |
<probo-accept-button> | Wraps a button that records “accept all” consent. |
<probo-reject-button> | Wraps a button that records “reject all” consent. |
<probo-customize-button> | Wraps a button that opens the preference panel. |
<probo-preference-panel> | Container for per-category consent toggles. |
<probo-category-list> | Renders a <template> once per cookie category. Fills data-slot="name" and data-slot="description". |
<probo-category-toggle> | Binds the checkbox inside it to the category’s consent state. |
<probo-cookie-list> | Renders a <template> once per cookie in the category. Fills data-slot="name" and data-slot="duration". |
<probo-save-button> | Wraps a button that saves the current preference draft. |
<probo-settings-button> | Floating button to re-open preferences. Accepts a position attribute (bottom-left or bottom-right). Hidden automatically when reopen-widget="custom" is set on the root. |
<probo-settings-link> | Inline element (e.g. a footer link) that opens the preference panel on click. Automatically hides the floating settings button. Place it anywhere on the page. |
Custom Re-open Link
Section titled “Custom Re-open Link”By default, a floating settings button lets visitors re-open the preference panel after they’ve made their choice. If you’d rather use your own trigger — for example, a link in the footer — use the <probo-settings-link> element:
<footer> <probo-settings-link> <a href="#">Cookie Settings</a> </probo-settings-link></footer>When <probo-settings-link> connects, it automatically sets reopen-widget="custom" on the banner root, which hides the built-in floating button. Clicking the link opens the preference panel.
This works with all three integration methods — script tag, themed banner, and headless components. The <probo-settings-link> element finds the banner root automatically, regardless of how the SDK is loaded.
Alternatively, you can set the reopen-widget="custom" attribute directly and handle the click yourself. With the 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-reopen-widget="custom"></script>With the themed banner:
<probo-cookie-banner banner-id="YOUR_BANNER_ID" base-url="https://your-probo-instance.com/api/cookie-banner/v1/" reopen-widget="custom"></probo-cookie-banner>With headless components:
<probo-cookie-banner-root banner-id="YOUR_BANNER_ID" base-url="BASE_URL" reopen-widget="custom"> <!-- ... banner and preference panel ... --></probo-cookie-banner-root>Language Detection
Section titled “Language Detection”The SDK automatically resolves the visitor’s language using the following priority:
- Explicit attribute — The
langattribute on the component (ordata-langon the script tag) - Page language — The
langattribute on the<html>element, using the base language subtag (e.g.frfromfr-FR) - Browser language — The browser’s
navigator.language, using the base subtag - Default language — The banner’s default language configured in the console (defaults to
en)
The resolved language is sent to the API when fetching the banner configuration. The API returns all UI text, category names, and descriptions in the resolved language. If no translation exists for that language, the API falls back to the banner’s default language.
Built-in Languages
Section titled “Built-in Languages”New banners include translations for four languages out of the box:
| Code | Language |
|---|---|
en | English |
fr | French |
de | German |
es | Spanish |
You can customize these translations and add new languages from the Probo console. All banner text is translatable, including:
- Banner title and description
- Button labels (accept all, reject all, customize, save preferences)
- Preference panel title and description
- Cookie detail labels (description, duration)
- ARIA accessibility labels
- Privacy policy link text
- Content placeholder text (shown when resources are blocked)
- Duration labels (years, months, days, etc.)
Forcing a Language
Section titled “Forcing a Language”To override auto-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 titled “Matching the Page Language”In most cases, you don’t need to set a language explicitly. If your page has a lang attribute on the <html> element, the SDK picks it up automatically:
<html lang="fr">This is the recommended approach for multilingual sites that already set the lang attribute as part of their i18n setup.
Events
Section titled “Events”The SDK emits custom events that bubble through the DOM. Listen on the root element or any ancestor:
| Event | Detail | Description |
|---|---|---|
probo-ready | { config } | Fired when the banner configuration has been loaded from the API. The config object includes language (resolved language), default_language, available_languages, and texts (all UI strings for the resolved language). |
probo-state | { state, prev } | Fired when the banner UI state changes. States: loading, banner, panel, hidden. |
probo-consent | { action, consent_data } | Fired after consent is recorded. Actions: ACCEPT_ALL, REJECT_ALL, CUSTOMIZE. |
probo-reopen-widget | { value } | Fired when the reopen-widget attribute changes on the root. Values: "floating", "custom". |
document.addEventListener("probo-consent", (e) => { console.log("Consent action:", e.detail.action);});How Consent Is Stored
Section titled “How Consent Is Stored”- Client-side: A
probo_consentcookie stores the visitor’s consent state. The cookie’smax-ageis set to the consent expiry configured on the banner (in days). It usesSameSite=Lax. - Server-side: Every consent action is recorded via the Probo API with the banner version, visitor ID, action type, anonymized IP address, and user agent. IP addresses are anonymized before storage (IPv4 last octet zeroed, IPv6 masked to /48) — the full IP is never persisted. See 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 look up existing consent when the visitor returns. - Offline resilience: If the API is unreachable when consent is recorded, the request is queued in
localStorageand retried automatically on the next page load.
Integrations
Section titled “Integrations”The SDK ships with built-in integrations that automatically sync consent state with third-party services. Both integrations are enabled by default — they activate only when the corresponding flags are configured on your cookie categories in the Probo console. No extra code is needed.
Google Consent Mode
Section titled “Google Consent Mode”The SDK pushes Google Consent Mode v2 signals to gtag() or dataLayer, keeping Google tags in sync with visitor consent.
How it works:
- On load, the SDK sends a
consent("default", ...)call that sets all configured consent types to"denied". - When the visitor makes a choice, the SDK sends a
consent("update", ...)call with"granted"or"denied"for each consent type based on the visitor’s per-category choices.
Configuration is driven by the GCM consent types field on each cookie category in the Probo console. Map categories to Google consent types like analytics_storage, ad_storage, ad_user_data, or ad_personalization. Categories without GCM consent types configured are ignored.
The integration detects window.gtag or window.dataLayer automatically. If neither is present, it does nothing.
PostHog
Section titled “PostHog”The SDK syncs consent with PostHog’s capture opt-in/opt-out mechanism, ensuring PostHog only tracks visitors who have granted consent.
How it works:
- On load, the SDK calls
posthog.opt_out_capturing()to ensure no data is collected before consent. - When the visitor grants consent for all PostHog-mapped categories, the SDK calls
posthog.opt_in_capturing(). If any mapped category is denied, it callsposthog.opt_out_capturing().
Configuration is driven by the PostHog consent flag on each cookie category in the Probo console. Enable it on the categories that should gate PostHog tracking (typically Analytics).
The integration requires the PostHog JavaScript SDK to be loaded on your page separately. It detects window.posthog automatically. If PostHog is not present, it does nothing.