Cookie ? / Pourquoi cette bannière
Concrètement, c’est quoi un cookie ?
Un cookie est une petite donnée enregistrée dans votre navigateur par un site web.
D’autres technologies similaires existent (localStorage
, sessionStorage
, IndexedDB, etc.) et sont
traitées de la même façon par la loi lorsqu’elles servent à vous reconnaître ou vous suivre.
La bannière permet à l’internaute d’accepter, de refuser ou de gérer des préférences par finalité.
Ce que permet (et impose) la bannière
- Transparence : description claire des finalités (statistiques, marketing…).
- Choix utilisateur : accepter, refuser, ou n’autoriser que certaines catégories.
- Preuve & révocabilité : le choix est enregistré et peut être modifié à tout moment (ex. lien “Politique en matière de cookies” en pied de page).
Références légales (UE & France)
- Directive ePrivacy (2002/58/CE), art. 5(3) — dépôt/lecture d’informations sur l’équipement terminal (cookies, traceurs) uniquement avec consentement préalable, sauf exception « strictement nécessaire » au service demandé.
- France – Loi Informatique & Libertés, art. 82 — transposition de l’art. 5(3) ePrivacy : information claire et complète + possibilité de s’opposer ; consentement requis pour les traceurs non essentiels ; exemptions pour le strictement nécessaire.
- RGPD :
- Art. 4(11) — définition du consentement : libre, spécifique, éclairé et univoque.
- Art. 7 — conditions du consentement : démontrable, réversible, et aussi facile à retirer qu’à donner.
- Art. 6(1)(a) — base légale « consentement » lorsque des données personnelles sont traitées via ces traceurs.
- CNIL — le refus des cookies doit être aussi simple que l’acceptation ; contrôles et mises en demeure en cas de non-conformité.
Obligation légale :
la bannière est-elle obligatoire ?
- Oui, bannière obligatoire dès qu’un traceur (cookie, localStorage, etc.) sert à une finalité non strictement nécessaire (ex. statistiques « classiques », marketing, personnalisation, profiling, A/B test…). → Il faut un consentement préalable et la possibilité de refuser aussi simplement qu’accepter. (ePrivacy art. 5(3) / LIL art. 82, règles CNIL)
- Pas de bannière requise si le site n’utilise que des traceurs strictement nécessaires au service (ex. session, sécurité, panier, équilibrage de charge). (exemptés de consentement)
- Mesure d’audience exemptée (cas particuliers) : certaines stats « 1ʳᵉ partie » peuvent être dispensées de consentement si toutes les conditions CNIL sont respectées (finalité exclusivement statistique, portée limitée à l’éditeur, durée/portée réduites, pas de recoupement, IP tronquée, etc.). Dans ce cas, pas de bannière de consentement nécessaire, mais information claire à fournir.
⚠️ Le fait qu’un cookie soit « 1ʳᵉ partie » (et non « tiers ») ne le rend pas automatiquement légal sans consentement. S’il n’est pas strictement nécessaire et ne remplit pas une exemption CNIL (ex. audience sous conditions), la bannière reste obligatoire.
Installation
Via npm / yarn / pnpm
npm install @synapxlab/cookie-consent
# ou
yarn add @synapxlab/cookie-consent
pnpm add @synapxlab/cookie-consent
Dans votre bundle (ex: src/js/bundle.js
) :
import '@synapxlab/cookie-consent'; // charge la bannière
// (facultatif) window.CookieConsent?.open();
Via balise <script>
Placez ces scripts avant votre JS principal :
<script src="https://unpkg.com/@synapxlab/cookie-consent/dist/cookie.js"></script>
Ou téléchargement local :
<script src="/assets/js/cookie.js"></script>
⚛️ React (Vite / CRA)
// src/main.jsx
import '@synapxlab/cookie-consent';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
🟩 Vue 3 (Vite)
// src/main.js
import '@synapxlab/cookie-consent';
import { createApp } from 'vue';
import App from './App.vue';
createApp(App).mount('#app');
🅰️ Angular (CLI)
// src/main.ts
import '@synapxlab/cookie-consent';
import { bootstrapApplication } from '@angular/platform-browser';
import { AppComponent } from './app/app.component';
bootstrapApplication(AppComponent);
🔶 Svelte / SvelteKit
// Svelte : src/main.js
import '@synapxlab/cookie-consent';
import App from './App.svelte';
new App({ target: document.getElementById('app') });
// SvelteKit (client)
import { onMount } from 'svelte';
onMount(() => import('@lockness/cookie'));
⏭️ Next.js (App Router)
// app/layout.tsx
'use client';
import { useEffect } from 'react';
export default function RootLayout({ children }) {
useEffect(() => { import('@synapxlab/cookie-consent'); }, []);
return (<html><body>{children}</body></html>);
}
🌀 Nuxt 3
// plugins/cookie.client.ts
import '@synapxlab/cookie-consent';
export default defineNuxtPlugin(() => {});
SF Symfony (Webpack Encore)
// assets/app.js
import '@synapxlab/cookie-consent'; // avant vos intégrations tierces
import './styles/app.scss';
// templates/base.html.twig
{{ encore_entry_script_tags('app') }}
Utilisation
Le script injecte la bannière au chargement. Les catégories sont cachées par défaut et
s’affichent uniquement quand l’utilisateur clique sur « Les préférences ». Les choix sont
stockés dans localStorage
sous la clé politecookiebanner
.
<div id="openpolitecookie" class="credits"> <a href="#">[Politique en matière de cookies]</a> </div>
API
// Ouvrir la bannière (showPrefs=true ⇒ onglet Préférences directement visible)
window.CookieConsent.open(true);
// Effacer les préférences et rouvrir en mode Préférences
window.CookieConsent.reset();
Clé de stockage : localStorage['politecookiebanner']
.
Outils de test rapide
Afficher le code des buttons
const resetBtn = document.getElementById('btn-reset-consent');
const openBtn = document.getElementById('btn-open-consent');
resetBtn?.addEventListener('click', () => {
if (window.CookieConsent?.reset) {
window.CookieConsent.reset(); // ouvre la bannière en mode préférences
} else {
try { localStorage.removeItem('politecookiebanner'); } catch {}
alert('Consentement effacé. Rechargez la page avec F5 pour voir la bannière.');
}
});
openBtn?.addEventListener('click', () => {
if (window.CookieConsent?.open) {
window.CookieConsent.open(true); // ouvre directement avec préférences visibles
} else {
const link = document.querySelector('#openpolitecookie a');
if (link) { link.dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true })); }
}
});
“Effacer le consentement” supprime les préférences stockées (localStorage). “Ouvrir la fenêtre de préférences” affiche la bannière en mode Préférences.
✅ Strictement nécessaire → toujours actif (non refusables).
❌ Statistiques / Marketing refusés → rien ne doit être chargé.
Exemple : ne charger Google Analytics que si “Statistiques” est consenti
const startcall=(prefs)=>{
console.log('Préférences reçues:', prefs);
if (prefs?.statistics) {
// Charger Google Analytics loadGoogleAnalytics();
}
if (prefs?.marketing) {
// Charger pixels marketing loadMarketingScripts();
}
if (prefs?.cookies) {
// Activer cookies fonctionnels enableFunctionalCookies();
}
}
document.addEventListener('DOMContentLoaded', () => {
if (window.CookieConsent) {
const prefs = window.CookieConsent.getPreferences();
if (prefs) startcall(prefs);
}
document.addEventListener('cookieConsentChanged', (event) => {
startcall(event.detail.preferences);
});
});
Personnalisation CSS
La bannière utilise des variables CSS (custom properties). C’est le moyen le plus simple d’adapter les couleurs/contrastes à votre charte sans toucher au JS et sans recoder le SCSS.
Variables disponibles
:root{
--cc-bg: #fff;
--cc-border: #e5e7eb;
--cc-accent: #9b6b5a; /* couleur d’accent (bouton Accepter, switch ON) */
--cc-text: #111827;
--cc-muted: #6b7280;
--cc-line: #e5e7eb;
--cc-surface: #f3f4f6;
}
src/scss/cookie.scss
puis re-générez le bundle.
Thèmes multiples
La bannière lit ses couleurs via des variables CSS. On peut donc créer plusieurs
thèmes en générant des classes utilitaires (ex. .cookie-theme-brown
, .cookie-theme-dark
)
qui surchargent ces variables, sans toucher au JS.
// src/scss/cookie.scss (extrait)
$cookie-themes: (
default: ( bg:#fff, text:#111827, muted:#6b7280, line:#e5e7eb, surface:#f3f4f6, accent:#9b6b5a ),
dark: ( bg:#0b1220, text:#e5e7eb, muted:#94a3b8, line:#1f2937, surface:#141b2b, accent:#9b6b5a ),
blue: ( bg:#ffffff, text:#0f172a, muted:#475569, line:#e2e8f0, surface:#f1f5f9, accent:#2563eb )
);
// Génère .cookie-theme-XXX qui définissent les variables CSS
Commutateur de thème (démo)
Ces boutons ne sont là que pour la démo. En prod, choisissez un thème et gardez-le.
Exemple de page (démo)
<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Gérer le consentement aux cookies</title>
</head>
<body class="cookie-theme-default">
<footer>
<div id="openpolitecookie"><a href="#">[Politique en matière de cookies]</a></div>
</footer>
<!-- IMPORTANT : la bannière avant votre JS -->
<script src="/assets/js/cookie.js"></script>
<script src="/assets/js/bundle.js"></script>
</body>
</html>
Accessibilité
- Dialog ARIA :
role="dialog"
,aria-live="polite"
,aria-modal="true"
- Bouton de fermeture avec
aria-label
- Navigation clavier (tab) et focus visibles
Compatibilité navigateurs
Chrome, Firefox, Safari, Edge (versions récentes). iOS/Android WebView modernes. Pas de dépendance à jQuery.
Développement
git clone https://github.com/synapxLab/cookie-consent.git
cd cookie-consent
npm install
npm run dev # dev-server avec HMR
npm run build # build production minifié
Sortie par défaut : /assets/js/cookie.js
(bannière) et /assets/js/bundle.js
(site).
Build & déploiement
Via npm (recommandé)
npm install @synapxlab/cookie-consent
import '@synapxlab/cookie-consent';
dans votre code- Build avec votre bundler habituel (Webpack, Vite, etc.)
Via CDN
- Ajoutez le script :
<script src="https://unpkg.com/@synapxlab/cookie-consent/dist/cookie.js"></script>
- Ajoutez le lien de gestion :
<div id="openpolitecookie"><a href="#">Gérer mes cookies</a></div>
- Implémentez la logique de chargement conditionnel
Licence
MIT — utilisez, modifiez, redistribuez librement. Merci de conserver la mention de licence.
Code source disponible sur GitHub. Contributions et suggestions bienvenues !