Introduzione
CookiePilot è una piattaforma per la gestione del consenso (CMP), conforme al GDPR, al Codice Privacy (D.lgs. 196/2003) e alle Linee guida cookie del Garante, oltre che a Google Consent Mode v2.
Per chi è pensato
- Titolari di siti: attivazione senza scrivere codice.
- Sviluppatori: API, eventi, integrazioni con GTM.
- Agenzie: white-label, gestione multi-dominio.
Guida rapida
Passo 1: Registrazione
- Crea un account su app.cookiepilot.io/register.
- Aggiungi il tuo dominio nel pannello e copia la API key (formato
cp_live_...).
Passo 2: Installa il codice
Un'installazione diretta consiste in due script nell'<head>, in questo ordine.
Passo 2a: Consenso predefinito (stub inline). Incolla questo per primo, prima di qualsiasi altro script (cookiepilot.js, GA, GTM, tag pubblicitari e di tracciamento):
<script>"use strict";(function(){window.dataLayer=window.dataLayer||[];var d={ad_storage:"denied",ad_user_data:"denied",ad_personalization:"denied",analytics_storage:"denied",functionality_storage:"denied",personalization_storage:"denied",security_storage:"granted",wait_for_update:500},h=false;try{for(var i=0;i<window.dataLayer.length;i++){var x=window.dataLayer[i];if(x&&x[0]==="consent"&&x[1]==="default"){h=true;break}}}catch(err){}if(!h&&window.dataLayer.length)window.dataLayer.unshift(["consent","default",d]);window.gtag=function(){window.dataLayer.push(arguments)};if(!h)window.gtag("consent","default",d);var a=document.cookie.match(/(^|)cookiepilot_consent=([^;]+)/);if(a){try{var e=JSON.parse(decodeURIComponent(a[2]));window.gtag("consent","update",{analytics_storage:e.analytics?"granted":"denied",ad_storage:e.marketing?"granted":"denied",ad_user_data:e.marketing?"granted":"denied",ad_personalization:e.marketing?"granted":"denied",functionality_storage:e.preferences?"granted":"denied",personalization_storage:e.preferences?"granted":"denied",security_storage:"granted"})}catch(err){}}})();</script>
Questo snippet inline imposta subito ogni categoria su denied (con wait_for_update: 500), così lo stato predefinito di Google Consent Mode v2 è pronto prima che si carichi qualsiasi altra cosa. Per un visitatore di ritorno legge il consenso salvato direttamente dal cookie e invia un consent update.
Passo 2b: Script del banner. Aggiungilo subito dopo lo stub inline:
<!-- CookiePilot -->
<script async src="https://cdn.cookiepilot.io/cookiepilot.js" data-cpkey="TWOJ_KLUCZ"></script>
Passo 3: Configura il banner
Nel pannello: Dominio → Configurazione → Aspetto:
- posizione del banner (in alto, in basso, modale),
- colori e testi,
- un pulsante flottante "Impostazioni cookie" per i visitatori di ritorno.
Integrazione con Google Tag Manager
Con GTM installi CookiePilot tramite un unico tag Custom HTML che imposta lo stato di consenso predefinito e carica il banner nella fase più iniziale di GTM. Non ti serve un file stub separato né un secondo tag.
Tag: CookiePilot - Consent Init + Banner
In GTM, crea un tag Custom HTML (Tag → Nuovo → HTML personalizzato) e incolla:
<script>"use strict";
(function() {
window.dataLayer=window.dataLayer||[];var d={ad_storage:"denied",ad_user_data:"denied",ad_personalization:"denied",analytics_storage:"denied",functionality_storage:"denied",personalization_storage:"denied",security_storage:"granted",wait_for_update:500},h=false;try{for(var i=0;i<window.dataLayer.length;i++){var x=window.dataLayer[i];if(x&&x[0]==="consent"&&x[1]==="default"){h=true;break}}}catch(err){}if(!h&&window.dataLayer.length)window.dataLayer.unshift(["consent","default",d]);window.gtag=function(){window.dataLayer.push(arguments)};if(!h)window.gtag("consent","default",d);var a=document.cookie.match(/(^|)cookiepilot_consent=([^;]+)/);if(a){try{var e=JSON.parse(decodeURIComponent(a[2]));window.gtag("consent","update",{analytics_storage:e.analytics?"granted":"denied",ad_storage:e.marketing?"granted":"denied",ad_user_data:e.marketing?"granted":"denied",ad_personalization:e.marketing?"granted":"denied",functionality_storage:e.preferences?"granted":"denied",personalization_storage:e.preferences?"granted":"denied",security_storage:"granted"})}catch(err){}}
var s = document.createElement('script');
s.src = 'https://cdn.cookiepilot.io/cookiepilot.js?cpkey=' + encodeURIComponent('TWOJ_KLUCZ');
document.head.appendChild(s);
})();
</script>
Trigger: Consent Initialization - All Pages. Il tag deve attivarsi una volta per pagina. I tag Google (GA4, Google Ads), Facebook Pixel e gli altri tag di marketing NON usano il trigger Consent Initialization; si attivano più tardi (Consent Checks o un trigger che dipende dal consenso). Salva il tag e pubblica il container GTM.
Ordine e trigger
| Ordine | Tag | Trigger |
|---|---|---|
| 1 | CookiePilot - Consent Init + Banner | Consent Initialization - All Pages |
| 2 | GA4, Google Ads, UET | All Pages (Consent Mode gestisce da sé il consenso) |
| 3 | Facebook Pixel, TikTok, LinkedIn, ecc. | Custom Event cookiepilot_consent_update + condizione di consenso (vedi sotto) |
Tag non Google (Facebook Pixel, TikTok, LinkedIn)
Google Consent Mode copre solo i tag Google. Per ogni altro script, il widget invia un evento al dataLayer a ogni cambio di consenso:
dataLayer.push({
event: 'cookiepilot_consent_update',
cookiepilot_consent: {
necessary: true,
analytics: true,
marketing: true,
preferences: false
}
});
L'evento si attiva anche a ogni visita di un utente di ritorno (quando il widget legge il cookie del consenso), quindi il trigger GTM funziona a ogni visita, non solo alla prima decisione.
Schema condiviso (fallo una volta sola)
Configuri questi tre elementi una volta sola, poi li riutilizzi per tutti i tag non Google.
- Trigger (Trigger → Nuovo → Evento personalizzato): nome evento
cookiepilot_consent_update. Nessuna condizione, nessun "Una volta per pagina" (il tag deve poter scattare di nuovo dopo una decisione modificata). - Variabile Data Layer per ogni categoria che usi:
- Nome
cookiepilot_consent.marketing→ variabile es.dlv.cp_marketing - Nome
cookiepilot_consent.analytics→ variabile es.dlv.cp_analytics - Nome
cookiepilot_consent.preferences→ variabile es.dlv.cp_preferences
- Nome
- Gruppo di trigger o una condizione sul trigger:
dlv.cp_marketing equals true(per i tag di marketing) o il campo pertinente.
In ciascuno degli esempi qui sotto, il Trigger è lo stesso Custom Event con una condizione aggiunta sulla variabile giusta.
Facebook Pixel
Tag in GTM: Tag → Nuovo → HTML personalizzato.
<script>
!function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
document,'script','https://connect.facebook.net/en_US/fbevents.js');
fbq('init', 'YOUR_PIXEL_ID');
fbq('track', 'PageView');
</script>
- Trigger:
cookiepilot_consent_update+ condizionedlv.cp_marketing equals true. - Opzioni di attivazione del tag: Una volta per pagina.
Facoltativamente, per la piena conformità con Facebook Limited Data Use, aggiungi un secondo tag che chiama fbq('consent','revoke') con il trigger dlv.cp_marketing equals false.
TikTok Pixel
Tag in GTM: Tag → Nuovo → HTML personalizzato.
<script>
!function (w, d, t) {
w.TiktokAnalyticsObject=t;var ttq=w[t]=w[t]||[];ttq.methods=["page","track","identify","instances","debug","on","off","once","ready","alias","group","enableCookie","disableCookie","holdConsent","revokeConsent","grantConsent"],ttq.setAndDefer=function(t,e){t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}};for(var i=0;i<ttq.methods.length;i++)ttq.setAndDefer(ttq,ttq.methods[i]);ttq.instance=function(t){for(var e=ttq._i[t]||[],n=0;n<ttq.methods.length;n++)ttq.setAndDefer(e,ttq.methods[n]);return e},ttq.load=function(e,n){var r="https://analytics.tiktok.com/i18n/pixel/events.js",o=n&&n.partner;ttq._i=ttq._i||{},ttq._i[e]=[],ttq._i[e]._u=r,ttq._t=ttq._t||{},ttq._t[e]=+new Date,ttq._o=ttq._o||{},ttq._o[e]=n||{};n=document.createElement("script");n.type="text/javascript",n.async=!0,n.src=r+"?sdkid="+e+"&lib="+t;e=document.getElementsByTagName("script")[0];e.parentNode.insertBefore(n,e)};
ttq.load('YOUR_TIKTOK_PIXEL_ID');
ttq.grantConsent();
ttq.page();
}(window, document, 'ttq');
</script>
- Trigger:
cookiepilot_consent_update+ condizionedlv.cp_marketing equals true. - Opzioni di attivazione del tag: Una volta per pagina.
ttq.grantConsent() è la nuova API di TikTok (introdotta nel 2024). Senza di essa, TikTok riceve dati con hash senza consenso, il che viola i termini.
LinkedIn Insight Tag
<script type="text/javascript">
_linkedin_partner_id = "YOUR_LINKEDIN_PARTNER_ID";
window._linkedin_data_partner_ids = window._linkedin_data_partner_ids || [];
window._linkedin_data_partner_ids.push(_linkedin_partner_id);
</script>
<script type="text/javascript">
(function(l) {
if (!l){window.lintrk = function(a,b){window.lintrk.q.push([a,b])};
window.lintrk.q=[]}
var s = document.getElementsByTagName("script")[0];
var b = document.createElement("script");
b.type = "text/javascript";b.async = true;
b.src = "https://snap.licdn.com/li.lms-analytics/insight.min.js";
s.parentNode.insertBefore(b, s);})(window.lintrk);
</script>
- Trigger:
cookiepilot_consent_update+ condizionedlv.cp_marketing equals true. - Opzioni di attivazione del tag: Una volta per pagina.
Hotjar
<script>
(function(h,o,t,j,a,r){
h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)};
h._hjSettings={hjid:YOUR_HOTJAR_ID,hjsv:6};
a=o.getElementsByTagName('head')[0];
r=o.createElement('script');r.async=1;
r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv;
a.appendChild(r);
})(window,document,'https://static.hotjar.com/c/hotjar-',".js?sv=");
</script>
- Trigger:
cookiepilot_consent_update+ condizionedlv.cp_analytics equals true. - Opzioni di attivazione del tag: Una volta per pagina.
Hotjar rientra in analytics, non in marketing (misura il comportamento, non gli annunci). Verifica la tua cookie policy: alcune aziende classificano Hotjar in modo diverso.
Microsoft Clarity
<script type="text/javascript">
(function(c,l,a,r,i,t,y){
c[a]=c[a]||function(){(c[a].q=c[a].q||[]).push(arguments)};
t=l.createElement(r);t.async=1;t.src="https://www.clarity.ms/tag/"+i;
y=l.getElementsByTagName(r)[0];y.parentNode.insertBefore(t,y);
})(window, document, "clarity", "script", "YOUR_CLARITY_PROJECT_ID");
</script>
- Trigger:
cookiepilot_consent_update+ condizionedlv.cp_analytics equals true. - Opzioni di attivazione del tag: Una volta per pagina.
Pinterest Tag
<script>
!function(e){if(!window.pintrk){window.pintrk = function () {
window.pintrk.queue.push(Array.prototype.slice.call(arguments))};var
n=window.pintrk;n.queue=[],n.version="3.0";var
t=document.createElement("script");t.async=!0,t.src=e;var
r=document.getElementsByTagName("script")[0];
r.parentNode.insertBefore(t,r)}}("https://s.pinimg.com/ct/core.js");
pintrk('load', 'YOUR_PINTEREST_TAG_ID');
pintrk('page');
</script>
- Trigger:
cookiepilot_consent_update+ condizionedlv.cp_marketing equals true. - Opzioni di attivazione del tag: Una volta per pagina.
Microsoft Ads (UET)
UET supporta Google Consent Mode dalla fine del 2023, quindi non serve un trigger Custom Event. Aggiungi il tag nel modo standard (All Pages, Una volta per pagina) e UET legge da solo ad_storage da GCM, che imposta il widget.
Mappatura delle categorie (riepilogo)
| Tag | Categoria | Campo in cookiepilot_consent |
|---|---|---|
| Facebook Pixel | marketing | marketing |
| TikTok Pixel | marketing | marketing |
| LinkedIn Insight | marketing | marketing |
| marketing | marketing | |
| Hotjar | analytics | analytics |
| Microsoft Clarity | analytics | analytics |
| Mixpanel, Amplitude | analytics | analytics |
| Intercom, Drift, Crisp | preferences | preferences |
| GA4, Google Ads, UET | (GCM, nessun trigger) | gestito da gtag('consent','update') |
API Reference
CookiePilot espone l'oggetto window.CookiePilot:
| Metodo | Descrizione |
|---|---|
CookiePilot.getConsent() | Lo stato attuale del consenso, o null se non è stata presa alcuna decisione. |
CookiePilot.acceptAll() | Consenso a tutte le categorie. |
CookiePilot.rejectAll() | Rifiuta tutto tranne necessary. |
CookiePilot.updateConsent(partial) | Aggiorna le categorie selezionate, es. { analytics: true }. |
CookiePilot.showSettings() | Apre il modale delle preferenze. |
CookiePilot.hideSettings() | Chiude il modale delle preferenze. |
CookiePilot.showMyConsent() / hideMyConsent() | Mostra/nasconde il pulsante flottante. |
Esempio
const consent = CookiePilot.getConsent();
// { necessary: true, analytics: true, marketing: false, preferences: false }
CookiePilot.updateConsent({ analytics: true });
document.getElementById('cookie-settings').addEventListener('click', () => {
CookiePilot.showSettings();
});
Link "Gestisci i cookie" nel footer
<a href="#" onclick="CookiePilot.showSettings(); return false;">Gestisci i cookie</a>
Eventi JavaScript
Il widget lancia un evento nativo cookiepilot:consent su window. Il listener deve essere registrato prima che il widget si carichi se vuoi intercettare l'evento per un visitatore di ritorno (il dispatch parte subito, non appena il widget si avvia):
<script>
window.addEventListener('cookiepilot:consent', (e) => {
if (e.detail.marketing) {
fbq('init', 'YOUR_PIXEL_ID');
}
});
</script>
<script src="https://cdn.cookiepilot.io/cookiepilot.js" data-cpkey="TWOJ_KLUCZ"></script>
e.detail contiene lo stesso payload di getConsent(). Per le integrazioni basate su GTM, usa invece l'evento dataLayer descritto sopra, perché il dataLayer è un array persistente e GTM recupera anche gli eventi storici.
Categorie di consenso
| Categoria | Descrizione | Predefinito |
|---|---|---|
necessary | Necessari al funzionamento del sito | Sempre attivi |
analytics | Statistiche e analisi | Consenso richiesto |
marketing | Pubblicità e remarketing | Consenso richiesto |
preferences | Personalizzazione, lingua | Consenso richiesto |
Mappatura su Google Consent Mode
| Categoria CookiePilot | Campi Consent Mode |
|---|---|
analytics | analytics_storage |
marketing | ad_storage, ad_user_data, ad_personalization |
preferences | functionality_storage, personalization_storage |
| (sempre) | security_storage: granted |
Google Consent Mode v2
La versione 2 ha aggiunto ad_user_data e ad_personalization (richiesti da marzo 2024 nell'UE/SEE per la pubblicità Google).
| Parametro | Descrizione |
|---|---|
ad_storage | Cookie pubblicitari |
analytics_storage | Cookie analitici |
ad_user_data | Invio dei dati utente a Google |
ad_personalization | Personalizzazione degli annunci |
functionality_storage | Cookie funzionali |
personalization_storage | Cookie di personalizzazione |
security_storage | Sempre granted |
Come funziona:
- Lo stub imposta ogni campo su
deniedin modo sincrono, conwait_for_update: 500. - Dopo la decisione dell'utente, il widget invia
gtag('consent', 'update', {...})usando la mappatura qui sopra. - Per un visitatore di ritorno, il punto 2 si attiva subito all'avvio del widget, in base al cookie.
Configurazione dell'aspetto
Nel pannello: Dominio → Configurazione:
- Aspetto: posizione, colori, layout (BAR / BOX / MODAL).
- Testi: titolo, descrizione, etichette dei pulsanti, descrizioni delle categorie. 13 lingue (EN, PL, DE, FR, ES, IT, NL, PT, SV, CS, RO, EL, HU).
- Pulsante del consenso: un pulsante flottante "Impostazioni cookie" mostrato dopo la prima decisione (in basso a sinistra/destra).
- CSS personalizzato: un campo per i tuoi stili. Il widget viene renderizzato nello Shadow DOM, quindi i selettori CSS del documento principale non funzioneranno. Usa solo questo campo.
Accessibilità (WCAG 2.1 AA)
- ✅ Navigazione da tastiera (Tab, Shift+Tab, Enter, Escape).
- ✅ Etichette ARIA, role="dialog", aria-modal.
- ✅ Focus trap nel modale.
- ✅ Supporto per screen reader (live region al cambio di stato).
- ✅ Design responsive.
Integrazioni
WordPress
Abbiamo un plugin ufficiale: CookiePilot su WordPress.org.
- Amministrazione WordPress → Plugin → Aggiungi nuovo → cerca "CookiePilot".
- Installa e attiva.
- Impostazioni → CookiePilot → incolla la API key dal pannello.
Il plugin inserisce da solo lo stub e il tag nell'<head> (nell'ordine corretto, prima degli altri script) e fornisce uno shortcode [cookiepilot_settings] per un link "Gestisci i cookie" nel footer.
Se preferisci non usare il plugin, usa "Insert Headers and Footers" e incolla lo snippet dal Passo 2 della Guida rapida nella sezione Header.
Shopify
- Negozio → Temi → Modifica codice.
- In
theme.liquid, incolla lo snippet prima di</head>.
Next.js
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html>
<head>
<Script
src="https://cdn.cookiepilot.io/cookiepilot.js"
data-cpkey="TWOJ_KLUCZ"
strategy="beforeInteractive"
/>
</head>
<body>{children}</body>
</html>
);
}
strategy="beforeInteractive" garantisce che lo script del banner venga eseguito presto. Ricorda che lo stub inline del Passo 2a (consenso predefinito) va aggiunto separatamente, nell'<head> prima di questo script, ad esempio tramite next/script con dangerouslySetInnerHTML o direttamente in app/layout.tsx.
FAQ
Lo script rallenta il sito?
Il bundle è di circa 12 KB gzip e si carica in modo asincrono. Nessun impatto sui Core Web Vitals.
Per quanto tempo viene conservato il consenso?
Cookie della decisione dell'utente: 365 giorni per impostazione predefinita (configurabile nel pannello). Eventi di analisi: 2 anni (TTL di ClickHouse).
L'evento cookiepilot_consent_update si attiva per i visitatori di ritorno?
Sì. Il widget legge il cookie all'avvio e invia l'evento al dataLayer. Il trigger Custom Event in GTM si attiva a ogni visita, non solo alla prima decisione.
Dove segnalo un problema?
kontakt@cookiepilot.io o la chat nel pannello.
Checklist di test post-deploy
Una volta installato CookiePilot, verifica la configurazione prima di lanciare le campagne pubblicitarie.
1. Test prima che l'utente dia il consenso
- Apri il sito in modalità in incognito e cancella i cookie del dominio.
- Apri DevTools → Network e ricarica la pagina.
- Prima di cliccare sul consenso, conferma che:
- non vengano creati cookie analitici/di marketing, es.
_ga,_gcl_*,_fbp,_ttp, - i tag di marketing non inviino richieste a Meta/TikTok/LinkedIn prima del consenso marketing,
- nel
dataLayerci sia lo stato predefinitodeniedperad_storage,ad_user_data,ad_personalizationeanalytics_storage.
- non vengano creati cookie analitici/di marketing, es.
2. Test dopo l'accettazione del consenso
- Clicca su "Accetta tutto".
- In DevTools, verifica che sia comparso l'evento
cookiepilot_consent_update. - Per i tag Google, verifica in GTM Preview / Tag Assistant che Consent Mode abbia portato lo stato a
grantedper le categorie pertinenti. - Per GA4, controlla in DebugView che gli eventi inizino ad arrivare dopo il consenso.
- Per Meta Pixel / TikTok / LinkedIn, verifica che i tag si attivino solo dopo l'evento
cookiepilot_consent_updatee la condizione di consenso marketing.
3. Test del rifiuto del consenso
- Cancella i cookie e ricarica la pagina.
- Clicca su "Rifiuta tutto".
- Conferma che i cookie e le richieste di marketing continuino a non attivarsi.
- Conferma che le funzionalità essenziali del sito continuino a funzionare.
4. Errori comuni
- Il tag GA4/Google Ads si attiva su
Consent Initializationinvece che su un trigger successivo. - Il Meta Pixel o il TikTok Pixel non ha una condizione su
cookiepilot_consent.marketing. - Un vecchio tracker hardcoded è ancora nell'
<head>prima di CookiePilot. - La documentazione o il template ha ancora una URL di script obsoleta o un vecchio attributo identificativo invece dell'attuale
cookiepilot.jscondata-cpkey.
Prova del consenso, esportazioni e DSAR
CookiePilot registra gli eventi di consenso così da poter ricostruire il contesto della decisione di un visitatore. Un record può includere l'orario dell'evento, il tipo di evento, il dominio, la URL della pagina o della sorgente, la versione del consenso, le categorie e la consent string quando disponibile, l'indirizzo IP anonimizzato, l'hash dello user-agent, il tipo di dispositivo e il browser.
Esportazioni
- Prova di consenso del singolo visitatore: JSON, CSV o HTML stampabile.
- Log di audit del dominio: CSV o JSON per un intervallo di date selezionato.
- Le esportazioni sono limitate alla tua organizzazione e ai domini a cui hai accesso.
Flusso DSAR
Un Owner o Admin può avviare una richiesta di accesso ai dati da una riga di consenso o dalla pagina DSAR nel pannello. Il pannello individua gli eventi del visitatore, mostra l'intervallo e consente di scaricare i file di prova. Una richiesta di cancellazione richiede una motivazione e viene registrata nel registro attività dell'organizzazione.
Limiti
Le esportazioni di audit del dominio usano l'intervallo di date selezionato e possono essere troncate per insiemi di risultati molto grandi. La conservazione del log dei consensi segue il piano attivo e la policy dell'account, perciò la documentazione pubblica non promette un numero fisso di anni.