Skip to main content

Web CMP

Implement a notice on a website using Javascript, as described below.


Latest changes

The last CMP web version is V32.0.1.

You will find amongst the latest changes:

  • Added a cache for backend calls to improve global navigation performance

  • The ability to manipulate consents of your users without displaying the CMP (e.g, for Youtube, Twitch or Twitter embeddings)

  • The replacement of a Continue without accepting by a clickable cross for users using Italian language to abide the latest Italian regulations.

  • The implementation of the notice has been simplified.

note

You can find more details on Release notes page.


Main steps to implement a web notice

info

You wish integrate AppConsent into shopify? See the dedicated page: Implément Appconsent with Shopify

1. Implement the notice

info

Open your HTML code source first.

  1. Go to Notices tab in AppConsent configuration interface
  2. Then under the notice you wish to integrate, copy the integration code using the "Copy" button

Quick start copie code

  1. Finally, paste the code in the <head> tag in your website

2. Add privacy center

With the GDPR, you have an obligation to provide a way for the user to be able to change their choices at any time and easily. That's why you need to add privacy center kit.

3. Results

Congratulations! You have now finished setting up the CMP, your code should look like this :

<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Your Website</title>
<!-- MANDATORY: BEGIN IAB STUB -->
<script type="text/javascript">
!function(){var e=function(){var e,t="__tcfapiLocator",a=[],n=window;for(;n;){try{if(n.frames[t]){e=n;break}}catch(e){}if(n===window.top)break;n=n.parent}e||(!function e(){var a=n.document,r=!!n.frames[t];if(!r)if(a.body){var s=a.createElement("iframe");s.style.cssText="display:none",s.name=t,a.body.appendChild(s)}else setTimeout(e,5);return!r}(),n.__tcfapi=function(){for(var e,t=arguments.length,n=new Array(t),r=0;r<t;r++)n[r]=arguments[r];if(!n.length)return a;if("setGdprApplies"===n[0])n.length>3&&2===parseInt(n[1],10)&&"boolean"==typeof n[3]&&(e=n[3],"function"==typeof n[2]&&n[2]("set",!0));else if("ping"===n[0]){var s={gdprApplies:e,cmpLoaded:!1,cmpStatus:"stub"};"function"==typeof n[2]&&n[2](s)}else a.push(n)},n.addEventListener("message",(function(e){var t="string"==typeof e.data,a={};try{a=t?JSON.parse(e.data):e.data}catch(e){}var n=a.__tcfapiCall;n&&window.__tcfapi(n.command,n.version,(function(a,r){var s={__tcfapiReturn:{returnValue:a,success:r,callId:n.callId}};t&&(s=JSON.stringify(s)),e&&e.source&&e.source.postMessage&&e.source.postMessage(s,"*")}),n.parameter)}),!1))};"undefined"!=typeof module?module.exports=e:e()}();
</script>
<!-- MANDATORY: END IAB STUB -->

<script type="text/javascript">
const configSFBXAppConsent = {
appKey: 'YOUR_APP_KEY'
// targetCountries: ['FR', 'UK', 'US'],
// forceGDPRApplies: true,
}
</script>
<script src="https://cdn.appconsent.io/tcf2-clear/current/core.bundle.js" defer async></script>
</head>
<body></body>
</html>


Migrated your old configuration

Since version 29.0.0, the implementation of cmp in your website has been simplified. For users who have configured the cmp before this release, we have provided a guide to migrate to the new configuration.

Configuration Migration Guide


Go further

Now that you have implemented your CMP you can put some extra commands or settings by reading the following instructions.

Passing commands in URL

You can pass commands to the CMP through the querystring. Querystring commands are evaluated on init.

?ac_cmd=show

The above link would show the CMP on init.

For more specific needs, other orders exist. Please contact the support.

You can also pass parameters to the command with the same mechanism. Parameters are passed as is from the querystring. Consider the following example:

?ac_cmd=show&jumpAt=banner

Commands / CMP Calls

CMP can be controlled through iAB's __tcfApi global function, as documented.

Custom calls are providen to operate the CMP, like displaying it, activating programmatic consent and so on. All Custom calls are asynchronous functions receiving an error-first callback and optional arguments, as follow:

init

Init the CMP with AppConsent credentials and additionnal configurations.

argument nametypeoptionalvalue
commandstring'init'
versionnumber2
callbackfunctionfunction(error: Error, state: State)
parameterObjectConfiguration

Callback returns the CMP's state, retrieved from either LocalStorage or server. State contains Consent and Vendorlist. This command performs at most one server call.

Basic Example
__tcfapi("init", 2, console.log, {
appKey: "YOUR_APPKEY",
});
Basic Example with i18n
__tcfapi("init", 2, console.log, {
appKey: "123",
i18n: {
buttons_acceptAll: { values: { en: "ACCEPT ALL" } },
},
});
Advanced example with passing ExternalID (UUID key)
__tcfapi("init", 2, console.log, {
appKey: "appKey",
uuid: "YOUR_ID_ABCD12345678",
debug: true,
storage: true,
i18n: {
banner_title: { values: { fr: "Démo i18n" } },
buttons_acceptAll: { values: { fr: "Démo i18n Accept" } },
},
});
Configuration object example
/**
* Configuration holds settings for the current CMP instance
* Can be overriden by passing it to the init custom command
*/
export const configuration = {
/**
* string - 🛂 MANDATORY credentials for the AppConsent API
*/
appKey: null,

/**
* true - activate verbose logging in the browser's console
*/
debug: false,

/**
* true - show keys instead of traductions for i18n keys
*/
debugI18n: false,

/**
* Object - contains blacklist and whitelist fields to block dynamically
* loaded third-party scripts and unblock them after the user consent (use if
* the target scripts aren't included with <script> tags)
* {
* blacklist: [], // RegExp[] - list of domains blocked until the user consent
* whitelist: [], // RegExp[] - list of allowed domains
* },
*/
dynamicallyLoadedScripts: {},

/**
* true - Enable Google Ads and Analytics blocking.
* Warning, to be used only if you have another tool that blocks Google Ads
* and Analytics the time of the user's choice
*/
enableGCM: false,

/**
* true - CMP will be displayed to all visitors from any country in the world
*/
forceGDPRApplies: false,

/**
* true - Force static fallback, bypassing the AppConsent API.
*/
forceStatic: false,

/**
* Client performs country detection on their own and
* decides to hide or display the CMP for each individual user.
*
* true - CMP will be displayed, tcData gdprApplies will be set to true
* false - CMP will stay hidden, tcData gdprApplies will be set to false
*/
gdprApplies: null,

/**
* true - Force iAB global mode operation. Consent is stored on .consensu.org
*/
global: false,

/**
* Object - Overrides translation keys
*/
i18n: {},

/**
* string - URL to the static fallback of the AppConsent Vendorlist.
*/
"static": null,

/**
* true - Use the localstorage (default)
* false - localstorage is ignored
* Function - retrieve a Storage object from this function
*/
storage: true,

/**
* Non-empty array of strings (country codes) is accepted or null
* CMP will be displayed to the provided list of country codes
* Example: ['FR,'IT','RU','US']
*/
targetCountries: null,

/**
* string[] - list of script URLs that should be loaded and executed
* after the user consent (use instead of <script> tags)
*/
thirdPartyScriptURLs: [],

/**
* string - domain of the AppConsent API
*/
url: '',

/**
* string - overrides AppConsent's uuid generation
*/
uuid: null,

/**
* Number - Defines maximum cache duration between two calls to hello.
* This does not change anything on consent expiration management or global consent management, only
* sets up the maximal period for a user already having a consent to check for a notice configuration change.
*/
cmpVersionCacheDuration: 30*60,

/**
* Object - Allows to define a redirection url after the user click for each button "refuse all", "accept all" and "continue without accept" for each view (main and settings).
* {
* main: {
* denyAll : 'someURL',
* acceptAll : 'someURL',
* continueWithoutAccepting : 'someURL',
* },
* settings : {
* denyAll : 'someURL',
* acceptAll : 'someURL',
* }
* }
*
*/
urlRedirect: null

/**
* Object - Allows you to define callbacks on the init and show commands
* init : Take two parameters : error and state
* show : Take error in parameter
* listener : Triggered each time the iab listener is triggered and takes 2 parameters :
* - tcData: TCData object
* - success: boolean
* choiceDone : Triggered only when the user has made his choice and takes 2 parameters :
* - tcData: TCData object
* - success: boolean
*/

callbacks: {
init: ( error, state ) => {},
show: ( error ) => {},
listener: (tcData, success) => {},
choiceDone: (tcData, success) => {},
}
}
Static mode example

A static example file can be found here: collector-fr.json

show

Displays the CMP for collecting user consents.

ArgumentTypeOptionalValue
commandstring'show'
versionnumber2
callbackfunctionfunction(error: Error)
parameterObjectShowOption
ShowOption = {
/**
* true - If a consent if present, won't bother the user
* false (default) - Show the banner no matter what
*/
lazy: Boolean,
/**
* null, 'banner'
* 'privacy'
*/
jumpAt: string,
};
Example 1:
__tcfapi("show", 2, console.log, {
lazy: false,
});
Example 2:
__tcfapi("show", 2, console.log, {
jumpAt: "privacy",
});

accept

Registers a full consent on the CMP, as the user would have clicked on the "accept everything" button. The default behavior is to prevent overwriting any existing consent. You can force overwriting by specifying a special force parameter.

Note that no matter the outcome, this call will hide the UI.

ArgumentTypeOptionalValue
commandstring'accept'
versionnumber2
callbackfunctionfunction(error: Error)
parameterObjectAcceptOption
Example:
__tcfapi("accept", 2, console.log);

deny

ArgumentTypeOptionalValue
commandstring'deny'
versionnumber2
callbackfunctionfunction(error: Error)
parameter
Example:
__tcfapi("deny", 2, console.log);

fakedeny

Forge a deny consentstring and return it to all vendors, without saving it as a user legitimate consent. This is useful to prevent unhonorable vendors from assuming lack of consent is one. This WONT hide the UI.

ArgumentTypeOptionalValue
commandstring'fakedeny'
versionnumber2
callbackfunctionfunction(error: Error)
parameter
Example:
__tcfapi("fakedeny", 2, console.log);

How heavy is this CMP ?

We're leveraging chunking to alleviate bandwidth. Code for the UI is only downloaded when user interaction is needed. Besides, we do have a nice size report

Tag managers compatibility

We've decided to not support directly tag managers, as implementation and usages varies. We strongly encourage you to use the standard TCF v2 API to achieve consent resolution for your tags. But it's very easy to interract with them.

For example, a GTM implementation could look like this, provided we only strive for a full consent:

__tcfapi("getTCData", 2, (tcData, ok) => {
if (ok) {
for (var c in tcData.purpose.consents) {
if (tcData.purpose.consents[c]) {
// Push events to GTM
window.dataLayer.push({ event: "purpose_" + c });
}
}
}
});

Or for Tag Commander:

__tcfapi("getTCData", 2, (tcData, ok) => {
if (ok) {
var tcVars = {};
for (var c in tcData.purpose.consents) {
if (tcData.purpose.consents[c]) {
// Build a TagCommander events object
tcVars["purpose_" + c] = "1";
}
}
// Push events to Tag Commander
window.tcEvents(null, "sfbx_consent_action", tcVars);
}
});

Very simple exemple :

__tcfapi("getTCData", 2, (tcData, success) => {
if (success) {
console.log(tcData.tcString);
} else {
// do something else
}
});

Will output your tcString V2 in your console :

CO3czkfO3czkfACAGAFRArCgAL_AAD_AAAqIGBtX_T5eb2vje3Zdt9tkaYwf55y3o -
wjhgaIse8NwIeH7BoGL2MwvBX4JiQCGBAEEiKBAQdlHGBcCQAAgIgBiTKMYk2MCzNKJLJAilMbc0NYCC1mnsHTmZCY7068O__zv3eBghBJgqXgEiQthASTZpRCmACEcQFSDgEoIQgIFLDQAEBOwKAj1AAAAQGAAEAAAAIIICAQACAABIRAAAAICAUAEQCAAEAI0BCAAiQIBYASJAEAAqBoSAEUQQgCEHBgFHKIEBQAAAAA.YAAAAAAAAAAA;

More information in the official IAB Documentation here.

Edition of consents without displaying the CMP

When you website embeds external integrations (Youtube, Twitch, Twitter, etc.), you may need to modify consents of a user (with their agreement) to give access to this content without redisplaying the CMP. To do this, you can use the updateStatus function. This is how to use it:

__tcfapi('updateStatus', 2, () => {}, [{t: <type>, id: <id>, status: <bool-value> }])

The list of possible types <type> is the following one:

1 - Purpose

2 - Extra purpose

3 - Special feature

4 - IAB vendor

5 - Extra vendor

The ID <id> is the one of the object you want to enable/disable. Its nature depends on the object represented by <type>. You can see the list of available types and IDs for your notice through getTCData call (see usage example here).

The value <bool-value> enables (true) or disables (false) for the tuple (<type>, <id>).

An error will be returned if the consent of the user does not exist yet, of if any of the input combinations (<type>, <id>) does not exist in the array in argument.

To find the latest updates of the CMP, see the Release Notes section.