Aller au contenu principal

Web CMP

Implémenter une notice sur un site web utilisant Javascript, comme décrit ci-dessous.


Changements récents

La dernière version de la CMP web est la version v28.7.15.

Parmi les derniers changements en date, vous pourrez trouver :

  • L'ajout d'un cache pour les appels backend pour améliorer la performance de navigation

  • La possibilité de manipuler les consentements de vos utilisateurs sans affichage de la CMP (idéal pour des encarts Youtube, Twitch, Twitter, etc).

  • Le remplacement de "continuer sans accepter" par une croix pour les utilisateurs utilisant la langue italienne, conformément aux nouvelles réglementations en vigueur.

note

Vous pouvez retrouver l'intégralité des notes de version ici.


Implémenter la CMP TCF V2

info

Ouvrez d'abord votre code source HTML.

1. Ajoutez le IAB STUB dans la section <HEAD> de toutes vos pages

L'IAB STUB est un bloc de code commun qui régit certains comportements obligatoires pour la CMP.

<!-- MANDATORY: BEGIN IAB STUB -->
<script type="text/javascript">
"use strict";!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 -->

2. Ajoutez l'eventListener dans la section <HEAD> de toutes vos pages

    <!-- ADD EVENTILISTNER -->
<script type="text/javascript">
(adsbygoogle=window.adsbygoogle||[]).pauseAdRequests=1,window.dataLayer=window.dataLayer||[],__tcfapi("addEventListener",2,function(e,n){if(n&&e.gdprApplies&&("tcloaded"===e.eventStatus||"useractioncomplete"===e.eventStatus)){if((adsbygoogle=window.adsbygoogle||[]).pauseAdRequests=0,e.purpose.consents)
for(var s in window.dataLayer.push({AppConsent_IAB_PURPOSES:e.purpose.consents}),e.purpose.consents)e.purpose.consents[s]&&window.dataLayer.push({event:"appconsent_ctrl_"+s});var o,a;e.acExtraPurposes&&(o={},e.acExtraPurposes.forEach(function(e){o[e]=!0}),window.dataLayer.push({AppConsent_EXTRA_PURPOSES:o})),e.acExtraVendors&&(a={},e.acExtraVendors.forEach(function(e){a[e]=!0}),window.dataLayer.push({AppConsent_EXTRA_VENDORS:a})),e.purpose.consents&&e.vendor.consents&&("object"==typeof sfbxguardian&&e.purpose.consents[1]&&window.sfbxguardian.unblock(),"function"==typeof gtag&&(e.purpose.consents[1]&&e.vendor.consents[755]?gtag("consent","update",{analytics_storage:e.purpose.consents[7]||e.purpose.consents[9]?"granted":"denied",ad_storage:e.purpose.consents[3]?"granted":"denied "}):gtag("consent","update",{analytics_storage:"denied",ad_storage:"denied"})))}window.dataLayer.push({event:"appconsent_loaded"})});
</script>
<!-- END EVENTILISTNER -->

3. Mettez le init et le show dans le <body>

<script src="https://cdn.appconsent.io/loader-clear.js" defer async></script> 
<script type="text/javascript">
__tcfapi('init', 2, console.log, {
appKey: 'YOUR_APP_KEY'
// targetCountries: ['FR', 'UK', 'US'],
// forceGDPRApplies: true,
})
</script>

<script type="text/javascript">
__tcfapi('show', 2, console.log, {
lazy: true,
// hideRegexp: [
// '*.domain-where-not-to-show-cmp.com',
// 'https://other-domain-where-not-to-show-cmp.com',
// ],
})
</script>

Avec le RGPD, vous avez l'obligation de fournir un moyen à l'utilisateur de pouvoir modifier ses choix à tout moment et facilement. C'est pourquoi vous devez ajouter le kit privacy center. C'est pourquoi le privacyWidget est déjà installé MAIS vous pouvez choisir le lien privacy center si vous voulez l'ajouter sur un lien "Paramètres des cookies'" par exemple.

Pour plus d'informations ou pour personnaliser votre kit Privacy center, veuillez vous rendre sur cette page.

Attention

Faites attention à ne pas installer l'init js deux fois.

4. Utilisez l'appKey de votre notice

4.1. Obtenir l'appKey

  • Dans le menu de gauche, cliquez sur Notices.
  • Trouvez la notice que vous souhaitez mettre en application.
  • Une fenêtre apparaît avec l'appKey correspondante.
  • Utilisez l'icône de copie sur la droite pour copier votre appKey.

Obtenir l&#39;appkey

4.2. Insérer l'appKey dans votre code

Collez l'appKey dans le morceau de code que vous avez précédemment inséré dans le <body>, à ce niveau là : appKey: 'YOUR_APP_KEY'

5. [Optionnel] Add on - Contrôlez le GA4 ou le UA avec le mode consentement de Google

Voici un tag GA typique

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXXXXX-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}

gtag('js', new Date()); gtag('config', 'G-XXXXXXXXXX');
</script>

Nous ajoutons maintenant une commande spéciale qui initialisera gtag() avec les paramètres denied afin de ne pas déposer de cookies avant le choix de l'utilisateur. Le CMP va piloter le tag en fonction du bon consentement donné.

gtag("consent", "default", {
ad_storage: "denied",
analytics_storage: "denied",
});

Le code original devient le suivant :

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-XXXXXXXXX-1"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent', 'default', {
'ad_storage': 'denied',
'analytics_storage': 'denied'
});
gtag('js', new Date()); gtag('config', 'G-XXXXXXXXXX');
</script>

Félicitations, à ce stade, votre cmp est mis en œuvre et plus de 700 partenaires marketing (vendeurs IAB) et la famille Google Analytics sont dirigés par les choix de vos utilisateurs.

Voulez-vous contrôler d'autres tags ?

Votre CMP dispose d'une nouvelle fonction appelée "Guardian" qui vous permet de bloquer les balises très facilement. Veuillez consulter cette section pour en savoir plus.

6. Résultats

Félicitations ! Vous avez maintenant terminé la mis en place de la CMP, votre code doit ressembler à cela :

<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">
"use strict";!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 -->

<!-- ADD EVENTILISTNER -->
<script type="text/javascript">
(adsbygoogle=window.adsbygoogle||[]).pauseAdRequests=1,window.dataLayer=window.dataLayer||[],__tcfapi("addEventListener",2,function(e,n){if(n&&e.gdprApplies&&("tcloaded"===e.eventStatus||"useractioncomplete"===e.eventStatus)){if((adsbygoogle=window.adsbygoogle||[]).pauseAdRequests=0,e.purpose.consents)
for(var s in window.dataLayer.push({AppConsent_IAB_PURPOSES:e.purpose.consents}),e.purpose.consents)e.purpose.consents[s]&&window.dataLayer.push({event:"appconsent_ctrl_"+s});var o,a;e.acExtraPurposes&&(o={},e.acExtraPurposes.forEach(function(e){o[e]=!0}),window.dataLayer.push({AppConsent_EXTRA_PURPOSES:o})),e.acExtraVendors&&(a={},e.acExtraVendors.forEach(function(e){a[e]=!0}),window.dataLayer.push({AppConsent_EXTRA_VENDORS:a})),e.purpose.consents&&e.vendor.consents&&("object"==typeof sfbxguardian&&e.purpose.consents[1]&&window.sfbxguardian.unblock(),"function"==typeof gtag&&(e.purpose.consents[1]&&e.vendor.consents[755]?gtag("consent","update",{analytics_storage:e.purpose.consents[7]||e.purpose.consents[9]?"granted":"denied",ad_storage:e.purpose.consents[3]?"granted":"denied "}):gtag("consent","update",{analytics_storage:"denied",ad_storage:"denied"})))}window.dataLayer.push({event:"appconsent_loaded"})});
</script>
<!-- END EVENTILISTNER -->

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent', 'default', {
'ad_storage': 'denied',
'analytics_storage': 'denied'
});
gtag('js', new Date()); gtag('config', 'G-XXXXXXXXXX');
</script>

</head>
<body>

<script src="https://cdn.appconsent.io/loader.js" defer async></script>
<script type="text/javascript">
__tcfapi('init', 2, console.log, {
appKey: 'YOUR_APP_KEY'
// targetCountries: ['FR', 'UK', 'US'],
// forceGDPRApplies: true,
})
</script>

<script type="text/javascript">
__tcfapi('show', 2, console.log, {
lazy: true,
})
</script>


</body>
</html>

Aller plus loin

Maintenant que vous avez mis en place votre CMP, vous pouvez ajouter quelques commandes ou paramètres supplémentaires en lisant les instructions suivantes.

Passer des commandes dans l'URL

Vous pouvez passer des commandes au CMP par le biais du Querystring. Les commandes Querystring sont évaluées sur init.

?ac_cmd=show

Le code ci-dessus montre le CMP sur init.

Vous pouvez également passer des paramètres à la commande avec le même mécanisme. Les paramètres sont passés tels quels à partir du Querystring. Prenons l'exemple suivant : ?ac_cmd=show&jumpAt=banner

?ac_cmd=show&jumpAt=banner

Commandes/Appels CMP

La CMP peut être contrôlée par la fonction globale __tcfApi de l'IAB, comme indiqué ici.

Des appels personnalisés sont prévus pour faire fonctionner la CMP, comme l'afficher, activer le consentement programmatique, etc. Tous les appels personnalisés sont des fonctions asynchrones qui reçoivent un rappel en cas d'erreur et des arguments optionnels, comme suit :

init

Init la CMP avec les références AppConsent et des configurations supplémentaires.

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

Le callback renvoie l'état de la CMP, récupéré soit sur LocalStorage soit sur le serveur. L'état contient Consent et Vendorlist. Cette commande effectue au maximum un appel au serveur.

Exemple de base
__tcfapi("init", 2, console.log, {
appKey: "YOUR_APPKEY",
});
Exemple de base avec i18n
__tcfapi("init", 2, console.log, {
appKey: "123",
i18n: {
buttons_acceptAll: { values: { en: "ACCEPT ALL" } },
},
});
Exemple avancé avec le passage de l'ExternalID (clé UUID)
__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" } },
},
});
Exemple configuration de object
/**
* Configuration holds settings for the current CMP instance
* Can be overriden by passing it to the init custom command
*/
export var configuration = {
/**
* string - 🛂 MANDATORY credentials for the AppConsent API
*/
appKey: null,

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

/**
* true - CMP will be displayed to all visitors from any country in the world
*/
forceGDPRApplies: false,
/**
* 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,

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

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

/**
* 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
* TODO see the section: "No section here"
*/
storage: true,

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

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

/**
* 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
};
Exemple mode statique

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

show

Affiche la CMP pour le recueil des consentements des utilisateurs.

argument nametypeoptionalvalue
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,
};
Exemple 1 :
__tcfapi("show", 2, console.log, {
lazy: false,
});
Exemple 2 :
__tcfapi("show", 2, console.log, {
jumpAt: "privacy",
});

accept

Enregistre un consentement complet sur la CMP, car l'utilisateur aurait cliqué sur le bouton accept everyhting. Le comportement par défaut est d'empêcher l'écrasement de tout consentement existant. Vous pouvez forcer l'écrasement en spécifiant un paramètre force.

Notez que quel que soit le résultat, cet appel dissimulera l'UI.

argument nametypeoptionalvalue
commandstring'accept'
versionnumber2
callbackfunctionfunction(error: Error)
parameterObjectAcceptOption
Exemple:
__tcfapi("accept", 2, console.log);

deny

argument nametypeoptionalvalue
commandstring'deny'
versionnumber2
callbackfunctionfunction(error: Error)
parameter
Exemple:
__tcfapi("deny", 2, console.log);

fakedeny

Forge un consentement de refus et le retourner à tous les vendors, sans le sauvegarder comme consentement légitime de l'utilisateur. Cela est utile pour éviter que des vendors peu scrupuleux ne présument que l'absence de consentement en est un. Cela NE CACHERA PAS l'interface utilisateur.

argument nametypeoptionalvalue
commandstring'fakedeny'
versionnumber2
callbackfunctionfunction(error: Error)
parameter
Exemple:
__tcfapi("fakedeny", 2, console.log);

Quel est le poids de la CMP ?

Nous tirons parti des fragments pour réduire la bande passante. Le code de l'interface utilisateur n'est téléchargé que lorsque l'interaction de l'utilisateur est nécessaire. De plus, nous avons un rapport de taille raisonnable

Compatibilité avec les Tag managers

Nous avons décidé de ne pas soutenir directement les tag managers, car la mise en œuvre et les usages varient. Nous vous encourageons vivement à utiliser l'API standard TCF v2 pour obtenir une résolution de consentement pour vos balises. Mais il est très facile d'interagir avec elles.

Par exemple, la mise en œuvre d'un GTM pourrait ressembler à cela, à condition que nous nous efforcions uniquement d'obtenir un consentement complet :

__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 });
}
}
}
});

Ou pour 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);
}
});

Obtention de l'objet du consentement en JS

Exemple très simple :

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

Permet de sortir votre tcString V2 dans votre console :

CO3czkfO3czkfACAGAFRArCgAL_AAD_AAAqIGBtX_T5eb2vje3Zdt9tkaYwf55y3o -
wjhgaIse8NwIeH7BoGL2MwvBX4JiQCGBAEEiKBAQdlHGBcCQAAgIgBiTKMYk2MCzNKJLJAilMbc0NYCC1mnsHTmZCY7068O__zv3eBghBJgqXgEiQthASTZpRCmACEcQFSDgEoIQgIFLDQAEBOwKAj1AAAAQGAAEAAAAIIICAQACAABIRAAAAICAUAEQCAAEAI0BCAAiQIBYASJAEAAqBoSAEUQQgCEHBgFHKIEBQAAAAA.YAAAAAAAAAAA;

Plus d'informations dans la documentation officielle de l'IAB : ici.

Edition des consentements sans affichage de la CMP

Lorsque votre site propose des intégrations externes (Youtube, Twitch, Twitter, etc.), vous pouvez avoir besoin de modifier les consentements d'un utilisateur à la volée, avec son accord, pour donner accès à ce contenu sans réafficher à l'utilisateur une CMP préalablement refusée. Pour cela, vous pouvez utiliser la fonction updateStatus. Celle-ci s'utilise de la façon suivante :

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

La liste des types <type> possibles est la suivante :

  1. Purpose
  2. Extra purpose
  3. Special feature
  4. IAB vendor
  5. Extra vendor

L'ID <id> est celui de l'objet que vous voulez activer ou désactiver. Sa nature dépend de l'objet représenté par <type>. Vous pouvez consulter la liste des types et ID disponibles pour votre notice via l'appel getTCData (voir exemple d'utilisation ici).

La valeur <bool-value> sert à activer (true) ou désactiver (false) la combinaison (<type>, <id>). Une erreur sera retournée si le consentement de l'utilisateur n'existe pas encore, ou si l'une des combinaisons (<type>, <id>) n'existe pas dans le tableau passé en entrée.

Pour retrouver les dernières mises à jour de la CMP, consultez la section Notes de versions.