Outil gratuit

Générateur de bandeau de consentement aux cookies

Choisissez vos catégories de cookies, rédigez le texte, sélectionnez une apparence — et récupérez un bandeau de consentement sans dépendances à coller sur n'importe quel site. Il enregistre le choix du visiteur, garde les scripts tagués bloqués tant que leur catégorie n'est pas acceptée, et peut être rouvert depuis un lien de pied de page.

Indispensables au fonctionnement du site. Toujours actifs, sans demande de consentement.
Mesure l'utilisation du site afin de l'améliorer.
Sert à personnaliser les publicités et à mesurer les campagnes.
Mémorise des choix comme la langue, la région et la mise en page.

Votre bandeau de consentement

Collez ceci juste avant la balise de fermeture body, sur chaque page.

<!-- Cookie consent banner - paste this just before </body> -->
<script>
(function () {
  var CFG = {
  "storageKey": "cookie_consent",
  "position": "bar",
  "theme": "light",
  "accent": "#a6144d",
  "title": "Nous utilisons des cookies",
  "message": "Nous utilisons des cookies pour faire fonctionner ce site, comprendre son utilisation et l'améliorer. Vous pouvez tout accepter, refuser ce qui est optionnel ou choisir par catégorie.",
  "policyUrl": "https://example.com/privacy",
  "policyLabel": "Lire notre politique de confidentialité",
  "accept": "Tout accepter",
  "reject": "Refuser l'optionnel",
  "prefs": "Préférences",
  "save": "Enregistrer mes choix",
  "categories": [
    {
      "id": "necessary",
      "label": "Strictement nécessaires",
      "desc": "Indispensables au fonctionnement du site. Toujours actifs, sans demande de consentement.",
      "required": true
    },
    {
      "id": "analytics",
      "label": "Analytique",
      "desc": "Mesure l'utilisation du site afin de l'améliorer.",
      "required": false
    },
    {
      "id": "marketing",
      "label": "Marketing",
      "desc": "Sert à personnaliser les publicités et à mesurer les campagnes.",
      "required": false
    }
  ]
};
  var KEY = CFG.storageKey;
  var doc = document;
  var box = null;

  function read() {
    try { return JSON.parse(localStorage.getItem(KEY) || 'null'); } catch (e) { return null; }
  }

  function save(consent) {
    consent.necessary = true;
    consent.date = new Date().toISOString();
    try { localStorage.setItem(KEY, JSON.stringify(consent)); } catch (e) {}
    unblock(consent);
    window.dispatchEvent(new CustomEvent('consentchange', { detail: consent }));
    if (typeof window.onConsentChange === 'function') window.onConsentChange(consent);
  }

  // Scripts the site parked behind a category run only once it is granted. Park
  // one by giving its tag type="text/plain" and data-consent="analytics".
  // (Deliberately described, not shown: a literal script tag written out here
  // would close this one early and truncate everything below it.)
  function unblock(consent) {
    var parked = doc.querySelectorAll('script[type="text/plain"][data-consent]');
    for (var i = 0; i < parked.length; i++) {
      var old = parked[i];
      if (!consent[old.getAttribute('data-consent')]) continue;
      var next = doc.createElement('script');
      for (var a = 0; a < old.attributes.length; a++) {
        var at = old.attributes[a];
        if (at.name !== 'type' && at.name !== 'data-consent') next.setAttribute(at.name, at.value);
      }
      next.text = old.text;
      old.parentNode.replaceChild(next, old);
    }
  }

  function styles() {
    var dark = CFG.theme === 'dark';
    var bg = dark ? '#161622' : '#ffffff';
    var fg = dark ? '#f4f4f8' : '#141a47';
    var muted = dark ? 'rgba(244,244,248,.72)' : 'rgba(20,26,71,.7)';
    var line = dark ? 'rgba(255,255,255,.14)' : 'rgba(20,26,71,.12)';
    var el = doc.createElement('style');
    el.textContent = [
      '.cc-root{position:fixed;z-index:2147483000;font:400 14px/1.55 system-ui,-apple-system,Segoe UI,Roboto,sans-serif;color:' + fg + ';box-sizing:border-box}',
      '.cc-root *,.cc-root *::before,.cc-root *::after{box-sizing:inherit}',
      '.cc-card{background:' + bg + ';border:1px solid ' + line + ';box-shadow:0 18px 48px rgba(0,0,0,.18);border-radius:14px;padding:20px}',
      '.cc-bar{left:0;right:0;bottom:0;padding:16px}',
      '.cc-bar .cc-card{display:flex;flex-wrap:wrap;gap:16px;align-items:center;justify-content:space-between;max-width:1120px;margin:0 auto}',
      '.cc-box{left:16px;bottom:16px;max-width:400px}',
      '.cc-modal{inset:0;display:flex;align-items:center;justify-content:center;padding:16px;background:rgba(10,10,20,.5)}',
      '.cc-modal .cc-card{max-width:520px;width:100%}',
      '.cc-title{margin:0 0 6px;font-size:16px;font-weight:700}',
      '.cc-text{margin:0;color:' + muted + '}',
      '.cc-text a{color:' + CFG.accent + ';font-weight:600}',
      '.cc-actions{display:flex;flex-wrap:wrap;gap:8px;margin-top:14px}',
      '.cc-bar .cc-actions{margin-top:0}',
      '.cc-btn{appearance:none;cursor:pointer;border:1px solid ' + line + ';border-radius:999px;padding:9px 18px;font:600 14px inherit;background:transparent;color:' + fg + '}',
      '.cc-btn-main{background:' + CFG.accent + ';border-color:' + CFG.accent + ';color:#fff}',
      '.cc-btn:focus-visible{outline:2px solid ' + CFG.accent + ';outline-offset:2px}',
      '.cc-cats{display:none;margin:14px 0 0;padding:14px 0 0;border-top:1px solid ' + line + '}',
      '.cc-cats.cc-open{display:block}',
      '.cc-cat{display:flex;gap:10px;align-items:flex-start;margin-bottom:12px}',
      '.cc-cat input{margin:3px 0 0;accent-color:' + CFG.accent + '}',
      '.cc-cat strong{display:block;font-size:14px}',
      '.cc-cat span{display:block;color:' + muted + ';font-size:13px}',
      '@media(max-width:640px){.cc-bar .cc-card{display:block}.cc-bar .cc-actions{margin-top:14px}.cc-btn{flex:1 1 auto}}'
    ].join('');
    doc.head.appendChild(el);
  }

  function build() {
    var stored = read() || {};
    var root = doc.createElement('div');
    root.className = 'cc-root cc-' + CFG.position;
    root.setAttribute('role', CFG.position === 'modal' ? 'dialog' : 'region');
    root.setAttribute('aria-label', CFG.title);
    if (CFG.position === 'modal') root.setAttribute('aria-modal', 'true');

    var card = doc.createElement('div');
    card.className = 'cc-card';

    var copy = doc.createElement('div');
    var h = doc.createElement('p');
    h.className = 'cc-title';
    h.textContent = CFG.title;
    var p = doc.createElement('p');
    p.className = 'cc-text';
    p.textContent = CFG.message + ' ';
    if (CFG.policyUrl) {
      var link = doc.createElement('a');
      link.href = CFG.policyUrl;
      link.textContent = CFG.policyLabel;
      p.appendChild(link);
    }
    copy.appendChild(h);
    copy.appendChild(p);

    var cats = doc.createElement('div');
    cats.className = 'cc-cats';
    var inputs = {};
    for (var i = 0; i < CFG.categories.length; i++) {
      var c = CFG.categories[i];
      var row = doc.createElement('label');
      row.className = 'cc-cat';
      var cb = doc.createElement('input');
      cb.type = 'checkbox';
      cb.checked = c.required || stored[c.id] === true;
      cb.disabled = !!c.required;
      var txt = doc.createElement('div');
      var name = doc.createElement('strong');
      name.textContent = c.label;
      var desc = doc.createElement('span');
      desc.textContent = c.desc;
      txt.appendChild(name);
      txt.appendChild(desc);
      row.appendChild(cb);
      row.appendChild(txt);
      cats.appendChild(row);
      inputs[c.id] = cb;
    }
    copy.appendChild(cats);

    var actions = doc.createElement('div');
    actions.className = 'cc-actions';
    function button(label, main, onClick) {
      var b = doc.createElement('button');
      b.type = 'button';
      b.className = 'cc-btn' + (main ? ' cc-btn-main' : '');
      b.textContent = label;
      b.addEventListener('click', onClick);
      actions.appendChild(b);
      return b;
    }
    function decide(granted) {
      var consent = {};
      for (var i = 0; i < CFG.categories.length; i++) {
        var c = CFG.categories[i];
        consent[c.id] = c.required ? true : granted === null ? !!inputs[c.id].checked : granted;
      }
      save(consent);
      close();
    }
    var prefsBtn = button(CFG.prefs, false, function () {
      var open = cats.classList.toggle('cc-open');
      prefsBtn.setAttribute('aria-expanded', open ? 'true' : 'false');
      saveBtn.style.display = open ? '' : 'none';
    });
    prefsBtn.setAttribute('aria-expanded', 'false');
    button(CFG.reject, false, function () { decide(false); });
    button(CFG.accept, true, function () { decide(true); });
    var saveBtn = button(CFG.save, false, function () { decide(null); });
    saveBtn.style.display = 'none';

    card.appendChild(copy);
    card.appendChild(actions);
    root.appendChild(card);
    doc.body.appendChild(root);
    box = root;
  }

  function close() {
    if (box && box.parentNode) box.parentNode.removeChild(box);
    box = null;
  }

  function open() {
    if (!box) build();
  }

  function start() {
    styles();
    var stored = read();
    if (stored) unblock(stored);
    else build();
    window.showConsentPreferences = open;
  }

  if (doc.readyState === 'loading') doc.addEventListener('DOMContentLoaded', start);
  else start();
})();
</script>

Comment l'utiliser

Trois étapes pour un bandeau opérationnel

1. Collez le snippet

Déposez le code généré juste avant la balise de fermeture body, sur chaque page. Il n'a aucune dépendance et n'ajoute aucune requête réseau.

2. Mettez vos scripts de tracking en attente

Passez le type d'une balise de tracking à text/plain et ajoutez data-consent="analytics". Le bandeau l'exécute dès que cette catégorie est acceptée — et jamais avant.

3. Laissez les visiteurs changer d'avis

Ajoutez un lien de pied de page qui appelle window.showConsentPreferences() pour rouvrir le panneau. Chaque décision déclenche aussi un événement consentchange que vous pouvez écouter.

FAQ

À propos du consentement aux cookies

Ce bandeau suffit-il à la conformité RGPD ?

Il vous donne les mécanismes attendus par les autorités : aucun cookie optionnel avant consentement, un refus aussi simple que l'acceptation, un choix par catégorie et la possibilité de revenir sur sa décision. La conformité dépend aussi de ce que vous exécutez réellement, du contenu de votre politique et du pays de vos visiteurs : considérez le code généré comme une base solide, pas comme un conseil juridique.

Comment empêcher des scripts de s'exécuter avant le consentement ?

Donnez à la balise de script le type="text/plain" et un attribut data-consent nommant sa catégorie. Le navigateur ne l'exécute pas, et le bandeau la réécrit en véritable balise de script dès que la catégorie est acceptée — lors de cette visite ou de la suivante, à partir de la décision enregistrée.

Où le choix du visiteur est-il stocké ?

Dans localStorage, sous la clé que vous choisissez, en un petit objet JSON avec un indicateur par catégorie et la date. Aucun cookie n'est déposé par le bandeau lui-même et rien n'est envoyé à un serveur : il fonctionne donc sur un site purement statique.

Puis-je le restyler ?

Oui. La position, le thème et la couleur d'accent sont des options ici, et chaque élément du CSS généré est préfixé par cc-, ce qui vous permet de surcharger les règles depuis votre propre feuille de style sans toucher au snippet.

Ai-je encore besoin d'une plateforme de gestion du consentement ?

Pour un site unique avec quelques catégories, ce snippet suffit généralement. Dès que vous avez besoin de journaux de consentement, de plusieurs domaines ou d'une analytique qui respecte automatiquement le choix, le gestionnaire de consentement intégré de PulsePanda prend le relais.

Associé

Plus de PulsePanda

Un consentement que votre analytique respecte vraiment

PulsePanda intègre un gestionnaire de consentement — sans cookies par défaut, et la collecte s'arrête dès qu'une personne se retire. Pas de second prestataire, pas de code de liaison.

Commencer gratuitement