Cookie Consent
Gate analytics scripts behind cookie consent with integrations.cookies, and load an Osano or Termly consent banner on your docs site.
Jamdesk can withhold every analytics and tracking script (Google Analytics, Google Tag Manager, Plausible, Crisp chat, custom JavaScript, and Jamdesk's own built-in analytics) until a visitor consents to cookies. Jamdesk reads consent from the browser's localStorage. Any consent management platform (CMP) that records consent there works, including Osano and Termly.
No tracking runs before the visitor agrees. That helps you comply with privacy regulations such as the GDPR, CCPA, and the ePrivacy Directive.
How It Works
Set a localStorage key and the value that means "consent granted" in docs.json:
{
"integrations": {
"cookies": {
"key": "jamdesk_consent",
"value": "granted"
}
}
}With integrations.cookies set, no analytics script loads until localStorage["jamdesk_consent"] equals "granted". Scripts load as soon as your consent banner records acceptance, with no page reload. Revoked consent takes effect on the visitor's next full page load. Scripts already running in the current page keep running until the visitor navigates away or reloads.
key and value are required. A missing or empty key or value turns consent gating off. Scripts then load normally.
Gating applies to Jamdesk's built-in analytics too. Visitors who never consent are not counted. Expect lower pageview numbers in your project dashboard after you enable this.
Connecting Your Consent Banner
Most CMPs (including Osano and Termly) don't expose a stable localStorage flag for Jamdesk to read. They store consent in cookies or in values that change per visitor. Add a short bridge snippet in your CMP's own custom-code area instead. It writes jamdesk_consent when a visitor accepts. The snippet runs as part of the CMP, so it always runs. Jamdesk custom JavaScript can't do this job because it is itself gated.
The snippet writes granted on consent. It removes the key when consent is withdrawn. Gating then re-applies on the next page load.
Osano
Add your Osano script in docs.json:
{
"integrations": {
"osano": {
"scriptSource": "https://cmp.osano.com/YOUR_CUSTOMER_ID/YOUR_CONFIG_ID/osano.js"
}
}
}The script URL comes from your Osano dashboard. It always starts with https://cmp.osano.com/ and ends with /osano.js.
Then add this bridge in Osano (Consent Manager → your config → custom JavaScript):
function jdOsanoBridge(consent) {
if (consent && consent.ANALYTICS === 'ACCEPT') {
localStorage.setItem('jamdesk_consent', 'granted');
} else {
localStorage.removeItem('jamdesk_consent');
}
}
if (window.Osano && window.Osano.cm) {
jdOsanoBridge(window.Osano.cm.getConsent());
window.Osano.cm.addEventListener('osano-cm-consent-saved', jdOsanoBridge);
} else {
window.addEventListener('osano-cm-initialized', function () {
jdOsanoBridge(window.Osano.cm.getConsent());
window.Osano.cm.addEventListener('osano-cm-consent-saved', jdOsanoBridge);
});
}
Termly
Add your Termly script in docs.json:
{
"integrations": {
"termly": {
"scriptSource": "https://app.termly.io/resource-blocker/YOUR-WEBSITE-UUID?autoBlock=on"
}
}
}The URL comes from Termly's embed instructions for your website (the Resource Blocker script). The ?autoBlock=on query is optional. It turns on Termly's automatic script blocking.
Then add this bridge in Termly (your website → custom HTML/JavaScript):
function jdTermlyBridge() {
var s = Termly.getConsentState();
if (s && s.analytics) {
localStorage.setItem('jamdesk_consent', 'granted');
} else {
localStorage.removeItem('jamdesk_consent');
}
}
(function register() {
if (window.Termly && typeof Termly.on === 'function') {
Termly.on('consent', jdTermlyBridge);
try { jdTermlyBridge(); } catch (e) {}
} else {
setTimeout(register, 200);
}
})();
Osano and Termly load first in the page <head>, before any other script. Their automatic blocking depends on this.
If your CMP runs in strict or auto-blocking mode, allowlist *.jamdesk.app and your custom docs domain in its managed rules (Osano: classification/allowlist; Termly: Domain Rules or Custom Blocking Map). Otherwise the CMP may block your docs site's own assets and break the page.
Testing Your Setup
Gating runs only on your live, published site. The jamdesk dev local preview ignores consent configuration. Test it:
- Open your live docs site with an empty
localStorage. Analytics should not load (check the browser Network tab: no requests to Google, Plausible, or/api/ev). - In the browser console, run
localStorage.setItem("jamdesk_consent", "granted"). The scripts should load within about a second, without a reload.
Disabling Jamdesk Analytics Entirely
Turn off Jamdesk's built-in (cookieless) analytics for every visitor, regardless of consent:
{
"analytics": { "enabled": false }
}