Aller au contenu

Intégration du SDK JavaScript (client)

Le SDK HashEntry CMP est un script sans dépendance qui affiche le bandeau cookies, bloque les scripts que vous marquez jusqu’à ce que le visiteur les autorise, et enregistre chaque décision sur le serveur HashEntry. Il peut aussi enregistrer des approbations de documents (conditions, contrats, politiques) — voir Approbation de documents et signature.

Cette page décrit ce que le SDK fait aujourd’hui. Lorsqu’un comportement dépend d’un réglage du tableau de bord ou de votre propre balisage, elle le précise.


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

Le SDK charge depuis le serveur la configuration liée à votre clé API (design du bandeau, textes, catégories, documents, réglages de comportement) et détermine si un bandeau est nécessaire pour ce visiteur.

Deux conditions doivent être réunies pour qu’une décision relative aux cookies puisse être enregistrée sur le serveur :

  1. Le site est vérifié dans le tableau de bord. Les requêtes d’un site non vérifié sont rejetées avec 403 SITE_NOT_VERIFIED.
  2. Un document de politique de cookies est rattaché au site. Voir la section suivante.

Un consentement aux cookies n’est enregistré que s’il référence la version active exacte d’un document de type cookie_policy rattaché au site. La version de la politique acceptée fait partie de la preuve ; le SDK n’assouplit donc pas cette règle.

  • Si aucune politique de cookies publiée n’est rattachée, le SDK n’affiche pas le bandeau (ni le widget, ni le lien « Do Not Sell ») et maintient bloqués, dans toutes les régions, tous les scripts non essentiels balisés : un choix qui ne peut pas être enregistré comme preuve n’est pas recueilli. Les événements consent:error et error sont émis avec code: "COOKIE_POLICY_MISSING" et l’erreur est écrite dans la console du navigateur. CMP.accept() / CMP.reject() se résolvent avec success: false, error.code = "COOKIE_POLICY_MISSING" et pending_sync: false ; rien n’est stocké, appliqué ni mis en file d’attente. Dès qu’une politique est rattachée, le bandeau apparaît au chargement de page suivant et le visiteur se prononce sur cette version. Un consentement enregistré alors qu’une politique était rattachée reste valide.
  • Une décision n’est jamais retenue pour être envoyée plus tard avec une version de la politique que le visiteur n’a pas vue. Si une version antérieure du SDK a laissé une telle décision dans la file d’attente locale, elle est abandonnée (consent:error avec final: true, reprompt: true) et le visiteur est de nouveau sollicité.
  • La seule exception est le mode local sans data-site : rien n’est envoyé au serveur, le bandeau est donc affiché et les décisions restent dans le navigateur (local_only: true).
  • Si le consentement référence une version qui n’est pas la version active, le serveur répond 409 CONFIG_OUTDATED. Voir Nouveau consentement et changement de version des documents.

Ce que vous devez faire : créez un document de politique de cookies dans le tableau de bord, publiez une version dans chaque langue utilisée par votre bandeau, puis rattachez-le au site.


Seuls les scripts que vous marquez sont bloqués. Le SDK n’analyse pas la page à la recherche de traceurs et n’intercepte pas les scripts que vous laissez tels quels : une balise <script> normale s’exécute immédiatement, avec ou sans consentement.

Pour retenir un script, changez son type en text/plain et indiquez sa catégorie :

<!-- Script inline : ne s'exécute qu'une fois « analytics » autorisé -->
<script type="text/plain" data-cookie-category="analytics">
/* extrait de code analytics */
</script>
<!-- Script externe : utilisez data-src au lieu de src -->
<script type="text/plain" data-cookie-category="marketing"
data-src="https://connect.facebook.net/en_US/fbevents.js"></script>
  • Les noms de catégorie doivent correspondre aux clés de catégorie de votre bandeau (analytics, marketing, preferences, ou vos propres clés). Les scripts marqués necessary sont activés immédiatement, avant le chargement de la configuration.
  • Les scripts marqués qui sont ajoutés à la page ultérieurement (navigation SPA, injection de balises) sont également pris en charge.
  • Un script qui s’est déjà exécuté ne peut pas être arrêté. Lorsqu’un visiteur révoque une catégorie dont les scripts se sont exécutés sur la page en cours, le SDK supprime les cookies connus de cette catégorie et, par défaut, recharge la page (voir reload_on_revoke).
  • Lorsqu’une catégorie est révoquée, le SDK supprime les cookies / entrées de stockage listés pour cette catégorie dans la configuration de votre bandeau, ainsi qu’une courte liste intégrée de noms bien connus. Les cookies qu’il ne connaît pas ne sont pas supprimés, et les cookies tiers d’autres domaines ne peuvent pas être supprimés depuis votre page.

AttributDéfautDescription
data-site—Clé API du site. Requise en mode remote ; également nécessaire dans les autres modes pour que les décisions soient enregistrées sur le serveur.
data-modelocal-fallbackSource de la configuration : remote, local, local-fallback. Voir Modes de fonctionnement.
data-languageautoLangue du bandeau. auto utilise <html lang>, puis la langue du navigateur.
data-regionautoForce une région ou un cadre réglementaire (DE, US, gdpr, ccpa, none, …) à la place de la détection. Il s’agit de la région de conformité (les règles que suit la bannière) ; elle ne détermine ni le lieu de stockage des données ni l’hôte d’API appelé.
data-config—Configuration JSON inline (pour local / local-fallback).
data-debugfalsetrue affiche les journaux de débogage. Les erreurs et les avertissements sont toujours affichés dans la console.
data-headlessfalsetrue n’affiche aucune interface (bandeau, widget, lien « Do Not Sell »). Voir Mode headless.
data-consent-moderéglage du tableau de bordtrue / false force l’activation ou la désactivation de Google Consent Mode v2. Voir Google Consent Mode v2.
data-reload-on-revokeréglage du tableau de bordtrue / false remplace l’option de comportement reload_on_revoke.
data-modules—Modules à charger d’emblée, par exemple documents, preferences. Voir Bundles et modules à la demande.
data-module-basedossier du script lui-mêmeURL de base à partir de laquelle les fichiers de module sont chargés. Nécessaire uniquement lorsqu’ils ne sont pas servis à côté de cmp.js.
data-api-urlAPI HashEntryURL de base de l’API pour un proxy first-party ou un domaine personnalisé. Si la région de données de votre compte dispose de son propre hôte d’API, la réponse de configuration l’annonce (api_base_url) et le SDK l’utilise pour tous les appels suivants ; le code d’intégration généré dans le panneau contient alors déjà le data-api-url correspondant. Une valeur que vous définissez ici est toujours prioritaire.

window.CMP existe dès que le script s’est exécuté. Les méthodes qui enregistrent quelque chose renvoient une promesse avec un objet résultat ; elles ne lèvent pas d’exception.

CMP.ready(() => { /* configuration chargée, état du consentement évalué */ });
// Bandeau
CMP.show(); // ouvrir le bandeau (p. ex. depuis un lien de pied de page)
CMP.hide();
// Décisions — chacune renvoie Promise<ConsentResult>
CMP.accept(); // autoriser toutes les catégories
CMP.accept({ marketing: false }); // tout autoriser sauf marketing
CMP.reject(); // uniquement les nécessaires
CMP.withdraw(); // retirer le consentement stocké
// État
CMP.getConsent(); // ConsentState ou null
CMP.hasConsent('analytics'); // booléen (« necessary » vaut toujours true)
// Langue
CMP.setLanguage('de');
CMP.getLanguage();
CMP.setLocale('de', { ccpa: { optOut: 'Widersprechen' } }); // textes pour une langue
// Métadonnées : ajoutées à chaque consentement et approbation enregistrés ensuite
CMP.setMetadata({ order_id: 'ORD-54321' });
CMP.setMetadata('customer_id', 'CUST-999');
CMP.getMetadata();
// Forçage de la région, thème, URL de l'API, configuration locale
CMP.setRegion('DE');
CMP.setTheme({ primaryColor: '#0F766E' });
CMP.setApiUrl('/hashentry-api');
CMP.getApiUrl();
CMP.setConfig({ banner_config: { /* … */ } });
// Événements
CMP.on('consent:given', (payload) => {});
CMP.off('consent:given', handler);
// Documents (chargés à la demande — voir « Approbation de documents et signature »)
CMP.showDocumentApproval('terms-of-service', { language: 'en' });
CMP.approveDocument('terms-of-service', { /* … */ });

Le retrait désactive toutes les catégories non essentielles, supprime les cookies connus de ces catégories, passe Google Consent Mode à denied, envoie au serveur une décision withdrawn (si un consentement avait été stocké), supprime le consentement stocké dans le navigateur et — dans les régions opt-in — affiche de nouveau le bandeau. Si des scripts d’une catégorie révoquée se sont déjà exécutés sur la page, la page est rechargée, sauf si reload_on_revoke est désactivé.

Change la langue du bandeau ouvert et recharge la configuration pour cette langue, car les versions de document sont propres à chaque langue : les consentements ultérieurs référencent alors la version de la politique de cookies de la nouvelle langue. Si le bandeau n’a pas de traduction pour cette langue, il se rabat sur la langue par défaut du bandeau.

Les valeurs sont fusionnées et envoyées en tant que metadata avec chaque décision relative aux cookies et chaque approbation de document ultérieures. Le serveur accepte au plus 30 clés et environ 16 Ko de métadonnées par enregistrement.

<script>
window.__CMP_QUEUE = window.__CMP_QUEUE || [];
window.__CMP_QUEUE.push(['setLanguage', 'de']);
window.__CMP_QUEUE.push(['setMetadata', { order_id: 'ORD-12345' }]);
window.__CMP_QUEUE.push(['on', 'consent:given', (p) => console.log(p)]);
</script>

Les appels mis en file d’attente s’exécutent dans l’ordre au démarrage du SDK. Une langue définie de cette manière n’est pas remplacée par la détection automatique.


{
success: true,
consent_token: 'ct_…',
proof_hash: '…', // 64 caractères hexadécimaux
created_at: '2026-10-10T10:00:00+00:00',
idempotency_key: '…' // un UUID par action utilisateur, réutilisé à chaque nouvelle tentative
}

success vaut true uniquement lorsque le serveur a accepté l’enregistrement. Sinon :

{
success: false,
consent_token: '',
proof_hash: '',
created_at: '…',
error: { code: 'NETWORK_ERROR', status: 0, message: '…' },
pending_sync: true, // conservé dans la file d'attente locale, sera retenté
idempotency_key: '…'
}
  • error.code est le code machine du serveur ou l’un des codes du SDK ci-dessous ; error.status est le statut HTTP (0 lorsqu’aucune réponse n’a été reçue).
  • pending_sync: true signifie que la décision est appliquée dans le navigateur et attend dans une file d’attente locale (localStorage). Elle est retentée au chargement de page suivant, lorsque l’onglet redevient visible et lorsque le navigateur repasse en ligne, toujours avec le même idempotency_key, pendant 7 jours ou 12 tentatives au maximum.
  • local_only: true apparaît lorsqu’il n’y a rien à envoyer (par exemple en mode local sans data-site).

Le choix du visiteur est appliqué immédiatement dans le navigateur dans tous les cas ; le résultat vous indique si le serveur en possède un enregistrement. L’exception est COOKIE_POLICY_MISSING : la décision n’est ni stockée ni appliquée.

{ success: true, decision: 'accepted', consent_token: 'ct_…', proof_hash: '…', slug: 'terms-of-service', version: '2.0.0' }
{ success: false, slug: 'terms-of-service', version: '2.0.0', error: { code: 'DOCUMENT_VERSION_CHANGED', status: 409, message: '…' } }

Les approbations de documents ne sont jamais mises en file d’attente pour plus tard : si success ne vaut pas true, l’approbation n’a pas été enregistrée.


ÉvénementPayloadQuand
ready{}Démarrage terminé (également lorsque la configuration n’a pas pu être chargée).
banner:shown{ type } ou { headless: true, reason, config }Le bandeau a été affiché ou — en mode headless — doit être affiché par vos soins.
banner:hidden{ reason } ou { headless: true }Le bandeau a été fermé.
consent:given{ decision, categories, source }Une décision autre que « tout refuser » a été stockée localement.
consent:rejected{ decision, categories, source }« Tout refuser » a été stocké localement.
consent:changed{ oldCategories, newCategories }Une décision en a remplacé une précédente.
consent:withdrawn{ categories, cleanedCookies }CMP.withdraw() a été appelé.
consent:synced{ consent_token, idempotency_key }Le serveur a accepté un enregistrement (immédiatement ou depuis la file d’attente).
consent:error{ code, status, message, idempotency_key, pending_sync, final?, reprompt? }Un enregistrement n’a pas pu être transmis. final: true signifie qu’il a été abandonné.
document:approved{ slug, version, consentId }Une approbation de document a été enregistrée.
document:rejected{ slug, version }Le visiteur a refusé un document.
document:error{ slug, version, code, status, message }Un document n’a pas pu être chargé ou l’approbation n’a pas été enregistrée.
scripts:activated{ category, count }Des scripts marqués d’une catégorie ont été activés.
config:updated{ content_hash }Une configuration plus récente a remplacé celle du cache.
language:changed{ from, to }La langue a changé.
error{ scope, code, status, message, … }N’importe laquelle des erreurs ci-dessus ; scope vaut config, consent, module ou document.

consent:given / consent:rejected se déclenchent lorsque la décision est stockée dans le navigateur. Utilisez consent:synced (ou le résultat de la promesse) lorsque vous avez besoin de savoir que le serveur la détient.


Codes produits par le SDK lui-même :

CodeSignification
NOT_READYUne méthode de décision a été appelée avant le chargement de la configuration. Appelez-la à l’intérieur de CMP.ready().
COOKIE_POLICY_MISSINGAucun document de politique de cookies publié n’est rattaché au site. Le bandeau n’est pas affiché, les scripts non essentiels restent bloqués et la décision n’est ni stockée ni mise en file d’attente.
NETWORK_ERROR, TIMEOUTAucune réponse de l’API (délai d’expiration : 5 s par tentative).
HTTP_<status>Le serveur a répondu par une erreur qui ne comporte aucun code machine.
DOCUMENT_VERSION_CHANGEDLa version de document référencée n’est plus la version active ; l’enregistrement a été abandonné.
PENDING_EXPIREDUne décision en file d’attente n’a pas pu être transmise dans un délai de 7 jours et a été abandonnée.
MODULE_LOAD_FAILEDUn fichier de module (documents ou preferences) n’a pas pu être chargé. Également signalé par l’événement error avec scope: "module".
APPROVAL_TOKEN_REQUIREDLe document exige un jeton d’approbation à usage unique et aucun n’a été transmis (également renvoyé par le serveur).
CONFIG_UNAVAILABLELa configuration n’a pas pu être chargée (signalé via l’événement error).
UNEXPECTED_ERRORTout autre cas.

Les codes renvoyés par le serveur sont transmis tels quels. Les plus pertinents sont listés sur la page de l’API REST — par exemple CONFIG_OUTDATED, SITE_NOT_VERIFIED, ORIGIN_NOT_ALLOWED, RATE_LIMIT_EXCEEDED, CONSENT_LIMIT_EXCEEDED, APPROVAL_TOKEN_INVALID.

Réponses temporaires du serveur. 503 (API_KEY_LOOKUP_UNAVAILABLE, ADMISSION_UNAVAILABLE, QUEUE_OVERLOADED) et 429 RATE_LIMIT_EXCEEDED sont réessayées automatiquement avec la même idempotency_key ; le SDK attend la durée indiquée dans l’en-tête Retry-After. Si cette durée dépasse 5 secondes, le SDK n’attend pas dans la page : la décision reste dans la file d’attente locale (pending_sync: true) et est envoyée plus tard. Après 429 TOO_MANY_INVALID_API_KEYS, le SDK n’envoie plus aucune requête pendant cette vue de page et les décisions en file d’attente sont conservées ; vérifiez la valeur de data-site. Aucune de ces réponses n’affecte votre page : l’événement error est émis et les callbacks CMP.ready() s’exécutent tout de même.

Section intitulée « Réponses temporaires du serveur. 503 (API_KEY_LOOKUP_UNAVAILABLE, ADMISSION_UNAVAILABLE, QUEUE_OVERLOADED) et 429 RATE_LIMIT_EXCEEDED sont réessayées automatiquement avec la même idempotency_key ; le SDK attend la durée indiquée dans l’en-tête Retry-After. Si cette durée dépasse 5 secondes, le SDK n’attend pas dans la page : la décision reste dans la file d’attente locale (pending_sync: true) et est envoyée plus tard. Après 429 TOO_MANY_INVALID_API_KEYS, le SDK n’envoie plus aucune requête pendant cette vue de page et les décisions en file d’attente sont conservées ; vérifiez la valeur de data-site. Aucune de ces réponses n’affecte votre page : l’événement error est émis et les callbacks CMP.ready() s’exécutent tout de même. »

Nouveau consentement et changement de version des documents

Section intitulée « Nouveau consentement et changement de version des documents »

Quand le bandeau est affiché de nouveau. Le consentement stocké conserve le hash de contenu de la configuration du bandeau pour laquelle il a été donné. Le bandeau est affiché de nouveau lorsque :

  • le consentement a expiré (la durée de validité est définie dans le tableau de bord),
  • la structure des catégories / cookies du bandeau a changé, ou
  • une nouvelle version d’un document rattaché a été publiée — sauf si le réglage reconsent_on_doc_change du bandeau est désactivé, auquel cas seuls les changements de structure déclenchent un nouveau consentement.

Tant qu’un nouveau consentement est en attente dans une région opt-in, le choix précédent du visiteur reste en vigueur jusqu’à ce qu’il décide de nouveau.

Décisions en attente et changement de version d’un document. Si une décision n’a pas pu être transmise (hors ligne, page fermée, erreur du serveur) et que, au moment de la nouvelle tentative, la version de document qu’elle référence n’est plus la version active, le SDK :

  1. demande au serveur la configuration actuelle, en contournant le cache ;
  2. si la version est inchangée (le 409 était dû à un cache serveur à froid), envoie le même enregistrement une fois de plus ;
  3. si la version a changé, abandonne l’enregistrement, supprime le consentement stocké localement et affiche de nouveau le bandeau (consent:error avec code: "DOCUMENT_VERSION_CHANGED", final: true, reprompt: true).

Un enregistrement en attente n’est jamais renvoyé avec une version de document différente : le visiteur n’a pas vu cette version.


Régions, profils réglementaires et options de comportement

Section intitulée « Régions, profils réglementaires et options de comportement »

La région du visiteur est déterminée dans cet ordre : CMP.setRegion() → data-region → le résultat GeoIP du serveur dans la réponse de configuration (detected_region) → une estimation à partir du fuseau horaire du navigateur → le mode réglementaire fixe du bandeau → les règles les plus strictes (RGPD). Le SDK n’appelle jamais de service de géolocalisation tiers.

RégionCadreModèleComportement
UE / EEE, Suissegdpropt-inBandeau ; scripts marqués bloqués jusqu’à autorisation.
Turquiekvkkopt-inIdentique au RGPD.
Royaume-Uniuk_gdpropt-inIdentique au RGPD (voir uk_analytics_exemption).
Brésillgpdopt-inIdentique au RGPD.
Afrique du Sud, Canada, Chine, Corée du Sudpopia, pipeda, pipl, pipaopt-inLes règles de bandeau du RGPD sont appliquées.
États-Unisccpa — uniquement si activé, sinon gdpropt-out / opt-inVoir ccpa_opt_out_enabled.
Inconnuegdpropt-inRègles les plus strictes.
none (explicite)none—Pas de bandeau ; tous les scripts s’exécutent.

Dans chaque profil opt-in, le bandeau comporte toujours un bouton « Refuser » de même poids visuel que « Accepter », et aucune catégorie facultative n’est présélectionnée — quel que soit ce qu’indique le design du bandeau.

Trois options de comportement (bandeau → réglages de comportement dans le tableau de bord, banner_config.behavior dans une configuration locale) modifient cela :

OptionDéfautEffet
uk_analytics_exemptiondésactivéeVisiteurs du Royaume-Uni uniquement : les scripts marqués analytics peuvent s’exécuter avant une décision. Toutes les autres catégories nécessitent toujours un consentement et, une fois que le visiteur a décidé, c’est sa décision qui s’applique.
ccpa_opt_out_enableddésactivéeLes visiteurs détectés aux États-Unis obtiennent le modèle opt-out : les scripts s’exécutent par défaut, un lien « Do Not Sell or Share My Personal Information » est affiché, et un signal Global Privacy Control est appliqué une fois en tant qu’opt-out (consent_type: do_not_sell_opt_out). Lorsqu’elle est désactivée, les visiteurs américains obtiennent le bandeau opt-in.
reload_on_revokeactivéeRecharge la page lorsqu’un visiteur révoque une catégorie dont les scripts se sont déjà exécutés sur cette page. Ne la désactivez que si vos balises réagissent elles-mêmes aux changements de consentement.

Lorsque Consent Mode est activé, le SDK crée window.dataLayer et une fonction gtag s’ils n’existent pas, puis pousse :

  1. gtag('consent', 'default', { …all denied…, wait_for_update: 500 }) pendant le démarrage,
  2. gtag('consent', 'update', { … }) après chaque décision et à chaque chargement de page avec un consentement stocké.
SignalAccordé lorsque cette catégorie est autorisée
ad_storage, ad_user_data, ad_personalizationmarketing
analytics_storageanalytics
functionality_storage, personalization_storagepreferences
security_storagetoujours

Le SDK pousse également les événements de data layer hashentry_consent_default et hashentry_consent_update.

Mise en place :

  1. Activez Google Consent Mode pour le bandeau dans le tableau de bord, ou ajoutez data-consent-mode="true" à la balise script.
  2. Placez la balise script HashEntry au-dessus de votre balise Google / de votre extrait GTM.
  3. Si la commande default doit précéder les balises Google dès la toute première page vue d’un visiteur, utilisez data-consent-mode="true" et chargez cmp.js sans async. Le réglage du tableau de bord arrive avec la configuration qui, lors d’une première visite, est chargée de manière asynchrone ; lors des visites suivantes, il est lu dans la configuration mise en cache pendant le démarrage.

Consent Mode ne fait qu’envoyer des signaux. Les balises qui ne sont pas contrôlées par Consent Mode doivent toujours être marquées pour le blocage comme décrit ci-dessus.


Avec data-headless="true", le SDK n’affiche rien. Il continue de charger la configuration, de bloquer les scripts marqués, de mettre à jour Consent Mode et d’enregistrer les décisions.

CMP.on('banner:shown', ({ headless, reason, config }) => {
if (headless) openMyBanner(config); // reason : no_consent | expired | reconsent | withdrawn | api | opt_out
});
myAcceptButton.onclick = async () => {
const result = await CMP.accept({ analytics: true, marketing: false });
if (!result.success && !result.pending_sync) showError(result.error);
};

ModeSource de la configuration
remoteServeur uniquement. data-site est requis.
localLa page uniquement (CMP.setConfig, data-config ou <script type="application/json" id="cmp-config">).
local-fallback (défaut)Serveur ; s’il est injoignable, la configuration de la page.

Le mode détermine uniquement d’où provient la configuration. Les décisions sont envoyées au serveur dans tous les modes tant que data-site est défini. En mode local sans data-site, les décisions sont conservées uniquement dans le navigateur (local_only: true).

Une configuration locale a la même forme que la réponse du serveur :

<script type="application/json" id="cmp-config">
{
"banner_config": {
"layout": "bottom_bar",
"theme": { "primary_color": "#2563EB", "font_family": "system", "theme_mode": "auto" },
"behavior": { "show_widget": true, "show_reject_button": true, "show_settings_button": true },
"categories": [
{ "key": "necessary", "required": true, "default": true },
{ "key": "analytics", "required": false, "default": false,
"cookies": [{ "name": "_ga", "provider": "Google", "type": "cookie", "duration": "2 years" }] }
],
"languages": {
"default": "en",
"translations": {
"en": {
"title": "Cookie preferences",
"description": "We use cookies to measure how the site is used.",
"accept_button_text": "Accept all",
"reject_button_text": "Reject all",
"settings_button_text": "Manage preferences",
"save_selected_text": "Save selection",
"modal_title": "Cookie settings",
"always_active_text": "Always active",
"categories": {
"necessary": { "label": "Necessary", "description": "Required for the site to work." },
"analytics": { "label": "Analytics", "description": "Visitor statistics." }
}
}
}
}
}
}
</script>
<script src="https://tool.hashentry.com/cmp.js" data-site="YOUR_SITE_API_KEY" data-mode="local" async></script>

Lorsque data-site est défini, le SDK demande une fois au serveur, au démarrage, le document de politique de cookies, car un consentement doit référencer sa version. Si aucune politique n’est rattachée, le bandeau n’est pas affiché (COOKIE_POLICY_MISSING). Pour afficher le bandeau même lorsque le serveur est injoignable, incluez documents (la politique de cookies et sa version) dans la configuration de la page.


Tous les textes du bandeau (titre, description, boutons, noms de catégorie) proviennent de la configuration du bandeau — ils ne font pas partie du script.

Le SDK embarque un petit dictionnaire intégré, en anglais et en turc uniquement, pour les textes qui relèvent de sa propre interface : la boîte de dialogue « Do Not Sell », les boutons et la ligne d’erreur de l’approbation de documents, les en-têtes du tableau des cookies et le bouton de fermeture. Dans toute autre langue, ces textes se rabattent sur l’anglais, sauf si vous les fournissez :

CMP.setLocale('de', {
document: { approve: 'Ich stimme zu', reject: 'Ablehnen', saving: 'Wird gespeichert…', error: 'Ihre Zustimmung konnte nicht gespeichert werden. Bitte versuchen Sie es erneut.' },
ccpa: { link: '…', description: '…', cancel: 'Abbrechen', optOut: 'Widersprechen' },
cookies: { name: 'Name', provider: 'Anbieter', type: 'Typ', duration: 'Dauer', purpose: 'Zweck', category: 'Kategorie', count: '{n} Cookies', empty: 'Keine Cookies registriert.' }
});

Une configuration peut contenir les mêmes clés par langue sous languages.translations.<lang>.sdk_texts.


FichierContenuChargé
cmp.jsCœur et consentement aux cookiesPar votre balise script.
cmp-documents.<hash>.jsApprobation de documents (showDocumentApproval, approveDocument)Par cmp.js, la première fois que l’une de ces méthodes est appelée.
cmp-preferences.<hash>.jsCentre de préférences, tableau de détail des cookies, boîte de confirmation « Do Not Sell »Par cmp.js, la première fois que le visiteur ouvre l’un d’eux.

Vous n’ajoutez jamais de seconde balise script. Un site qui n’utilise que le bandeau cookies ne télécharge jamais le module de documents.

  • Le fichier du module est demandé au même emplacement que cmp.js (déduit du src du script).
  • Pour éviter le court délai lors du premier appel, chargez-le d’emblée : data-modules="documents".
  • Les appels effectués avant l’arrivée du module l’attendent simplement. S’il ne peut pas être chargé, la méthode se résout avec success: false et error.code = "MODULE_LOAD_FAILED" ; l’appel suivant réessaie.
  • Si le module preferences ne peut pas être chargé, le bandeau reste à l’écran avec ses boutons d’acceptation et de refus, l’événement error est émis avec scope: "module" et code: "MODULE_LOAD_FAILED", et le clic suivant réessaie. Pour ouvrir le centre de préférences sans délai, chargez-le d’emblée : data-modules="preferences".
  • Le nom du fichier contient un hash de contenu intégré dans cmp.js au moment du build, de sorte que cmp.js demande toujours le module construit avec lui.

Content Security Policy. Le module est chargé avec un élément <script> depuis la même origine que cmp.js ; le SDK n’utilise ni eval ni scripts inline. Pour les scripts, l’origine du SDK suffit :

script-src https://tool.hashentry.com;
connect-src https://system.hashentry.com;
  • Le SDK applique les styles de son interface avec des éléments <style> à l’intérieur de sa propre shadow root. Si votre politique restreint style-src, autorisez 'unsafe-inline' pour les styles ou utilisez un nonce : placez le nonce sur la balise cmp.js (<script nonce="…" …>) et le SDK le copie sur les éléments de style et sur la balise script du module qu’il crée.
  • Avec script-src 'strict-dynamic' et un nonce sur la balise cmp.js, le script du module est autorisé sans avoir à lister l’origine.
  • La boîte de dialogue d’approbation de documents affiche le document dans une iframe sandboxée sans src ; les scripts contenus dans le document ne s’exécutent pas.

Subresource Integrity. https://tool.hashentry.com/cmp.js est mis à jour sur place lorsqu’une nouvelle version du SDK est publiée ; un attribut integrity sur cette URL cesserait donc de fonctionner à la version suivante. Si vous avez besoin de SRI, hébergez sur votre propre origine une copie vérifiée de cmp.js avec les fichiers cmp-documents.*.js / cmp-preferences.*.js du même build et définissez integrity sur votre propre balise.

Auto-hébergement. Copiez cmp.js, cmp-documents.<hash>.js, cmp-preferences.<hash>.js, cmp-preferences.js et cmp-documents.js du même build dans un seul dossier. Si les fichiers de module se trouvent ailleurs, définissez data-module-base.


Pour faire passer les requêtes API par votre propre domaine, définissez data-api-url (ou CMP.setApiUrl) sur un chemin ou une URL de votre côté et transférez-le vers l’API HashEntry sans modifier le chemin situé après le préfixe :

<script src="https://tool.hashentry.com/cmp.js"
data-site="YOUR_SITE_API_KEY"
data-api-url="/hashentry-api" async></script>
# /hashentry-api/tool/v1/consents → https://system.hashentry.com/tool/v1/consents
location /hashentry-api/ {
proxy_pass https://system.hashentry.com/;
proxy_set_header Host system.hashentry.com;
proxy_ssl_server_name on;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

La signature de la requête couvre le chemin /tool/v1/... ; la requête en amont doit donc arriver avec exactement ce chemin. L’adresse IP enregistrée est celle que voit HashEntry ; le fait que l’adresse du visiteur soit tirée de X-Forwarded-For dépend de ce que le proxy soit considéré comme de confiance côté HashEntry — demandez au support avant de vous y fier.


NomOùFinalité
_he_consentcookie first-partyLa décision du visiteur (catégories, horodatages, jeton du serveur).
he_consent_tokenlocalStorageCopie de la même décision.
he_config_cachelocalStorageConfiguration mise en cache (jusqu’à 7 jours, revalidée en arrière-plan à chaque chargement).
he_pending_consentslocalStorageDécisions pas encore acceptées par le serveur (supprimées une fois transmises ; abandonnées après 7 jours).
he_gpc_appliedlocalStorageIndique qu’un opt-out GPC a été appliqué une fois.
he_sdk_reloadsessionStorageProtège la mise à jour automatique du SDK contre les boucles de rechargement.

Le SDK ne charge ni polices ni aucune autre ressource auprès de tiers.