Skip to content

JavaScript SDK (Client) Integration

The JS SDK aims for highest performance with zero dependencies on your web projects. Our platform solves your cookie management needs and allows you to easily obtain legally binding contract/policy consents.


Get started with a single script tag. Banner design, cookie categories, texts, and regional compliance (GDPR, KVKK, CCPA…) — all managed from the HashEntry Dashboard:

<head>
<script
src="https://tool.hashentry.com/cmp.js"
data-site="YOUR_SITE_API_KEY"
async
></script>
</head>

That’s it. The SDK fetches the config tied to your API key from the server; banner design, colors, language, categories, and behavior settings are all controlled from the dashboard.

Mark scripts that shouldn’t run before consent with type="text/plain". The SDK will automatically activate them once consent is given:

<!-- Google Analytics — won't run until "analytics" category is approved -->
<script type="text/plain" data-cookie-category="analytics">
(function(i,s,o,g,r,a,m){...})(window,document,'script','https://...');
</script>
<!-- Facebook Pixel — external script -->
<script type="text/plain" data-cookie-category="marketing"
data-src="https://connect.facebook.net/en_US/fbevents.js">
</script>

After the user closes the banner, two options are available to change preferences:

  1. Default icon: A persistent “Cookie Preferences” icon appears on screen. Its style and position are configured from the dashboard.
  2. Custom button: Hide the icon and call CMP.show() from your own footer link.

AttributeRequiredDefaultDescription
data-siteSite API key
data-modelocal-fallbackOperating mode: remote, local, local-fallback
data-languageautoBanner language (auto = detected from browser)
data-regionautoRegion override (auto = server GeoIP or config detection method)
data-configInline JSON config (local/local-fallback mode)
data-debugfalseDeveloper mode (console logs)
data-headlessfalseUI-less mode (use your own interface)

Available API after the SDK loads:

// Listen to SDK ready event
CMP.ready(() => {
console.log('HashEntry CMP loaded.');
});
// Programmatically show/hide the banner
CMP.show();
CMP.hide();
// Programmatic accept/reject
CMP.accept(); // Accept all
CMP.accept({ marketing: false }); // Accept except marketing
CMP.reject(); // Reject all
// Query current consent state
const consent = CMP.getConsent(); // { decision, categories, ... }
CMP.hasConsent('analytics'); // true / false
// Attach metadata to consent (e.g., order ID)
CMP.setMetadata({ order_id: 'ORD-54321', customer_id: 'CUST-999' });
// Open document (contract/policy) approval modal
CMP.showDocumentApproval('distance-sales-agreement', {
transaction_id: 'TRX-101'
}).then(result => {
if (result.approved) console.log("Approved!", result.proof_hash);
});
// Listen to events
CMP.on('consent:given', (data) => {
console.log("Consent given for:", data.categories);
});
CMP.on('banner:shown', () => { ... });
CMP.on('language:changed', ({ from, to }) => { ... });

To call the API before the script loads, use the queue:

<script>
window.__CMP_QUEUE = window.__CMP_QUEUE || [];
window.__CMP_QUEUE.push(['setMetadata', { order_id: 'ORD-12345' }]);
window.__CMP_QUEUE.push(['setRegion', 'DE']);
window.__CMP_QUEUE.push(['setLanguage', 'de']);
</script>

DashboardJS API (Runtime)
Banner design (logo, colors, corners)setLanguage — change language
Cookie categories and descriptionssetRegion — region override
Multi-language text templatessetMetadata — attach context to consent
GeoIP and regional rulesshow / hide — banner control
Document versionssetConfig — local config (advanced)
Default behavior settingson / off — event listeners

The SDK can operate in three different modes:

ModeBehaviordata-siteServer
remoteConfig fetched from serverRequiredRequired
localAll config provided from the pageOptionalNone
local-fallback (default)Tries server, falls back to local configOptionalPreferred

Run entirely without a server by embedding all config directly in the page. Ideal for test environments, offline scenarios, and situations where you want to use your own infrastructure.

Note: Local mode only determines the config source. Consent records are sent to the server in all modes — data-site API key is also used in local mode for consent recording.

Method 1 — <script id="cmp-config"> (recommended):

<head>
<script type="application/json" id="cmp-config">
{
"banner_config": {
"layout": "bottom_bar",
"region_detection": "timezone",
"theme": {
"primary_color": "#2563EB",
"background_color": "#FFFFFF",
"text_color": "#1F2937",
"button_style": "rounded",
"font_family": "system",
"theme_mode": "auto",
"widget_icon": "cookie",
"widget_position": "bottom_left"
},
"content": {
"title": "Cookie Preferences",
"description": "This website uses cookies to improve your experience.",
"accept_button_text": "Accept All",
"reject_button_text": "Reject All",
"settings_button_text": "Manage Preferences",
"save_selected_text": "Accept Selected",
"close_text": "Close",
"widget_label": "Cookie Settings"
},
"categories": [
{
"key": "necessary",
"label": "Necessary",
"description": "Required for basic site functionality.",
"required": true,
"default": true
},
{
"key": "analytics",
"label": "Analytics",
"description": "Used for visitor statistics.",
"required": false,
"default": false
},
{
"key": "marketing",
"label": "Marketing",
"description": "Used for personalized ads.",
"required": false,
"default": false
},
{
"key": "preferences",
"label": "Preferences",
"description": "Used for personalization.",
"required": false,
"default": false
}
],
"mobile_layout": "bottom_bar",
"behavior": {
"show_reject_button": true,
"show_settings_button": true,
"show_widget": true,
"show_powered_by": true,
"block_page_scroll": false,
"modal_layout": "sidebar_right",
"cookie_display_mode": "vendor",
"banner_animation": "slide_fade",
"modal_tabs": true,
"record_informational_consent": false
}
}
}
</script>
<script src="https://tool.hashentry.com/cmp.js" data-mode="local" data-language="en" async></script>
</head>

Method 2 — JavaScript API (ideal for SPAs):

window.__CMP_QUEUE = window.__CMP_QUEUE || [];
window.__CMP_QUEUE.push(['setConfig', {
banner_config: {
layout: 'bottom_bar',
region_detection: 'timezone',
theme: { primary_color: '#2563EB' , font_family: 'system' },
content: {
title: 'Cookie Preferences',
accept_button_text: 'Accept All',
reject_button_text: 'Reject All',
// ... all content fields
},
behavior: {
modal_layout: 'sidebar_right',
modal_tabs: true,
banner_animation: 'slide_fade'
},
categories: [
{ key: 'necessary', label: 'Necessary', description: 'Required.', required: true },
{ key: 'analytics', label: 'Analytics', description: 'Statistics.', required: false },
],
}
}]);

This is the default mode. Tries to fetch config from the server; if unreachable, falls back to the local config. If neither server nor local config is available but the user has previously given consent, their accepted categories will still be honored and permitted scripts will be activated.

<head>
<script type="application/json" id="cmp-config">
{ "banner_config": { "content": { "title": "Cookie Preferences", ... }, ... } }
</script>
<!-- data-mode can be omitted since local-fallback is the default -->
<script
src="https://tool.hashentry.com/cmp.js"
data-site="YOUR_SITE_API_KEY"
async
></script>
</head>

Advanced: Region Detection (region_detection)

Section titled “Advanced: Region Detection (region_detection)”

In remote mode, region info comes from the server’s GeoIP. In local or local-fallback mode, if data-region is not set, the region can be auto-detected via the region_detection config setting:

MethodHow It WorksNetwork Request
timezoneCountry estimate from browser timezone (120+ mappings)None
freegeoipFree IP → country service (3s timeout, falls back to timezone)Yes

Resolution order:

1. CMP.setRegion('DE') → explicit override (highest priority)
2. data-region="DE" → explicit override
3. config.region_detection → 'freegeoip' or 'timezone'
4. Fallback → EU → most restrictive region (GDPR applies)

In remote mode, translations are managed from the dashboard. In local mode, you can provide multi-language support in two ways:

Method 1: languages.translations in config

Section titled “Method 1: languages.translations in config”
{
"banner_config": {
"languages": {
"default": "en",
"translations": {
"en": {
"banner": { "title": "Cookie Preferences", "acceptAll": "Accept All", ... },
"categories": { "necessary": "Necessary", "necessaryDesc": "Required.", ... },
"modal": { "title": "Manage Cookies", ... },
"widget": { "label": "Cookie Settings" }
},
"de": {
"banner": { "title": "Cookie-Einstellungen", "acceptAll": "Alle akzeptieren", ... },
"categories": { "necessary": "Notwendig", ... },
"modal": { "title": "Cookie-Einstellungen verwalten", ... },
"widget": { "label": "Cookies" }
}
}
}
}
}
CMP.setLocale('de', {
banner: { title: 'Cookie-Einstellungen', acceptAll: 'Alle akzeptieren', ... },
categories: { necessary: 'Notwendig', ... },
modal: { title: 'Cookie-Einstellungen verwalten', ... },
widget: { label: 'Cookies' }
});
CMP.setLanguage('de');