This guide walks you through implementing Termly’s Consent Management Platform consent tracking and registering it with Tealium’s custom CMP interface.
Step 1: Capture Termly Consent State
The script allows Tealium to reference the current consent preferences when evaluating tag triggers. This code must be added on your Tealium extension tab.
(function insertTermlyScript() {
var script = document.createElement("script");
script.type = "text/javascript";
script.src =
"https://app.termly.io/resource-blocker/{TERMLYUUID}?autoBlock=on";
script.onload = function () {
if (typeof onTermlyLoaded === "function") {
onTermlyLoaded();
}
};
document.head.appendChild(script);
})();Step 2: Register Termly with Tealium as a Custom CMP
Using the following script, map Termly’s consent categories to Tealium iQ’s consent groups. This creates a full connection between Termly and Tealium’s Consent Manager.
//tv:1.1.0
//base:custom
/**
* @module utcm/integration
* @description Custom CMP component.
*/
function onTermlyLoaded() {
// Listen for Termly consent changes and store them globally
Termly.on("consent", ({ consentState }) => {
window.termlyConsentState = consentState; // expose for Tealium
});
}
(function termly(window) {
// CMP specific functionality and labels
window.tealiumCmpIntegration = window.tealiumCmpIntegration || {};
window.tealiumCmpIntegration.cmpName = "Termly CMP Integration";
window.tealiumCmpIntegration.cmpIntegrationVersion = "v1.1.0";
window.tealiumCmpIntegration.cmpFetchCurrentConsentDecision =
cmpFetchCurrentConsentDecision;
window.tealiumCmpIntegration.cmpFetchCurrentLookupKey =
cmpFetchCurrentLookupKey;
window.tealiumCmpIntegration.cmpCheckIfOptInModel = cmpCheckIfOptInModel;
window.tealiumCmpIntegration.cmpCheckForWellFormedDecision =
cmpCheckForWellFormedDecision;
window.tealiumCmpIntegration.cmpCheckForExplicitConsentDecision =
cmpCheckForExplicitConsentDecision;
window.tealiumCmpIntegration.cmpCheckForTiqConsent = cmpCheckForTiqConsent;
window.tealiumCmpIntegration.cmpConvertResponseToGroupList =
cmpConvertResponseToGroupList;
window.tealiumCmpIntegration.cmpConvertResponseToLookupObject =
cmpConvertResponseToLookupObject;
window.tealiumCmpIntegration.cmpAddCallbackToTriggerRecheck =
cmpAddCallbackToTriggerRecheck;
// --- Termly-specific categories ---
var consentCategories = [
"advertising",
"analytics",
"performance",
"social_networking",
"unclassified",
"essential",
];
function cmpCheckIfOptInModel() {
// Termly runs on opt-in (GDPR style)
return true;
}
function cmpFetchCurrentConsentDecision() {
return window.termlyConsentState || {};
}
function cmpFetchCurrentLookupKey() {
return "termly-consent-v1";
}
function cmpCheckForWellFormedDecision(cmpRawOutput) {
return typeof cmpRawOutput === "object";
}
function cmpCheckForExplicitConsentDecision(cmpRawOutput) {
if (!cmpRawOutput) return false;
return consentCategories.some(function (category) {
return cmpRawOutput[category] != null;
});
}
function cmpConvertResponseToLookupObject(cmpRawOutput) {
if (!cmpCheckForWellFormedDecision(cmpRawOutput)) return {};
var output = {};
consentCategories.forEach(function (category) {
if (cmpRawOutput[category]) {
output[category] = category;
}
});
return output;
}
function cmpConvertResponseToGroupList(cmpRawOutput) {
if (!cmpCheckForWellFormedDecision(cmpRawOutput)) return [];
return consentCategories.filter(function (category) {
return cmpRawOutput[category];
});
}
function cmpCheckForTiqConsent(cmpRawOutput, tiqGroupName) {
if (cmpCheckForWellFormedDecision(cmpRawOutput) !== true) return false;
tiqGroupName = tiqGroupName || "tiq-group-name-missing";
var allowedGroups = cmpConvertResponseToGroupList(cmpRawOutput);
return allowedGroups.indexOf(tiqGroupName) !== -1;
}
function cmpAddCallbackToTriggerRecheck(triggerRecheck) {
window.Termly?.on("consent", function ({ consentState }) {
window.termlyConsentState = consentState;
triggerRecheck();
});
}
})(window);
/*
// Debugging output — uncomment for testing
var outputString = `${tealiumCmpIntegration.cmpCheckIfOptInModel() ? 'Opt-in' : 'Opt-out'} Model
Checks:
- id: ${tealiumCmpIntegration.cmpFetchCurrentLookupKey()}
- well-formed: ${tealiumCmpIntegration.cmpCheckForWellFormedDecision(tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- explicit: ${tealiumCmpIntegration.cmpCheckForExplicitConsentDecision(tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- group list: ${JSON.stringify(tealiumCmpIntegration.cmpConvertResponseToGroupList(tealiumCmpIntegration.cmpFetchCurrentConsentDecision()))}
`
console.log(outputString);
*/
/*
// Optional: Debugging output
var outputString = `${tealiumCmpIntegration.cmpCheckIfOptInModel() ? 'Opt-in' : 'Opt-out'} Model
Checks:
- id: ${tealiumCmpIntegration.cmpFetchCurrentLookupKey()}
- well-formed: ${tealiumCmpIntegration.cmpCheckForWellFormedDecision(tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- explicit: ${tealiumCmpIntegration.cmpCheckForExplicitConsentDecision(tealiumCmpIntegration.cmpFetchCurrentConsentDecision())}
- group list: ${JSON.stringify(tealiumCmpIntegration.cmpConvertResponseToGroupList(tealiumCmpIntegration.cmpFetchCurrentConsentDecision()))}
`;
console.log(outputString);
*/
Step 3: Map Consent Categories
Below is a reference for how Termly’s cookie categories map to Tealium iQ consent groups:
| Termly Category | Tealium iQ Group |
|---|---|
performance |
performance |
analytics |
analytics |
advertising |
marketing |
social_networking |
social |
essential |
essential (optional) |
unclassified |
unclassified (optional) |