Documentație

Documentație CookiePilot

Platformă de gestionare a consimțământului pentru cookie-uri (CMP), conformă cu RGPD, cu Legea nr. 506/2004 și cu Google Consent Mode v2.

Introducere

CookiePilot este o platformă de gestionare a consimțământului pentru cookie-uri (CMP), conformă cu RGPD, cu Legea nr. 506/2004 privind prelucrarea datelor cu caracter personal în sectorul comunicațiilor electronice și cu Google Consent Mode v2.

Pentru cine

  • Proprietari de site-uri: implementare fără programare.
  • Dezvoltatori: API, evenimente, integrări cu GTM.
  • Agenții: white-label, gestionarea mai multor domenii.

Pornire rapidă

Pasul 1: Înregistrare

  1. Creează un cont pe app.cookiepilot.io/register.
  2. Adaugă domeniul în panou și copiază cheia API (format cp_live_...).

Pasul 2: Instalarea codului

Instalarea directă presupune două scripturi în secțiunea <head>, în această ordine.

Pasul 2a: Consimțăminte implicite (inline stub). Inserează-l primul, înaintea oricărui alt script (cookiepilot.js, GA, GTM, taguri de publicitate și de urmărire):

<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>

Acest snippet inline setează imediat toate categoriile pe denied (cu wait_for_update: 500), astfel încât starea implicită Google Consent Mode v2 este pregătită înainte ca orice altceva să se încarce. Pentru un utilizator care revine, citește imediat consimțământul salvat din cookie și trimite un consent update.

Pasul 2b: Scriptul bannerului. Adaugă-l imediat după inline stub:

<!-- CookiePilot -->
<script async src="https://cdn.cookiepilot.io/cookiepilot.js" data-cpkey="TWOJ_KLUCZ"></script>

Pasul 3: Configurarea bannerului

În panou: Domeniu → Configurare → Aspect:

  • poziția bannerului (sus, jos, modal),
  • culori și texte,
  • butonul plutitor „Setări cookie-uri” pentru utilizatorii care revin.

Integrarea cu Google Tag Manager

Prin GTM instalezi CookiePilot cu un singur tag Custom HTML, care setează imediat consimțămintele implicite și încarcă bannerul în cea mai timpurie fază a GTM. Nu ai nevoie de un fișier stub separat și nici de un al doilea tag.

În GTM creează un tag Custom HTML (Taguri → Nou → Cod HTML personalizat) și inserează:

<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. Tagul trebuie să se declanșeze o singură dată pe pagină. Tagurile Google (GA4, Google Ads), Facebook Pixel și alte taguri de marketing NU folosesc triggerul Consent Initialization, ci se declanșează mai târziu (Consent Checks sau un trigger condiționat de consimțământ). Salvează tagul și publică containerul GTM.

Ordine și triggere

OrdineTagTrigger
1CookiePilot - Consent Init + BannerConsent Initialization - All Pages
2GA4, Google Ads, UETAll Pages (Consent Mode gestionează singur consimțămintele)
3Facebook Pixel, TikTok, LinkedIn etc.Custom Event cookiepilot_consent_update + condiție de consimțământ (vezi mai jos)

Taguri din afara Google (Facebook Pixel, TikTok, LinkedIn)

Google Consent Mode gestionează doar tagurile Google. Pentru celelalte scripturi, widgetul trimite în dataLayer, la fiecare schimbare a consimțământului, un eveniment:

dataLayer.push({
  event: 'cookiepilot_consent_update',
  cookiepilot_consent: {
    necessary: true,
    analytics: true,
    marketing: true,
    preferences: false
  }
});

Evenimentul se trimite și la fiecare vizită a unui utilizator care revine (când widgetul citește cookie-ul cu consimțământul), astfel încât triggerul din GTM va funcționa la fiecare vizită, nu doar la prima decizie.

Pattern comun (se face o singură dată)

Aceste trei elemente le configurezi o singură dată, apoi le folosești pentru toate tagurile din afara Google.

  1. Trigger (Triggers → New → Custom Event): Event name cookiepilot_consent_update. Fără condiții, fără „Once per page” (tagul trebuie să se poată declanșa din nou după schimbarea deciziei).
  2. Data Layer Variable pentru fiecare categorie pe care o folosești:
    • Name cookiepilot_consent.marketing → variabilă, de ex. dlv.cp_marketing
    • Name cookiepilot_consent.analytics → variabilă, de ex. dlv.cp_analytics
    • Name cookiepilot_consent.preferences → variabilă, de ex. dlv.cp_preferences
  3. Trigger Group sau condiție în trigger: dlv.cp_marketing equals true (pentru tagurile de marketing) sau câmpul corespunzător.

În fiecare dintre exemplele de mai jos, Trigger este același Custom Event, la care se adaugă o condiție pe variabila potrivită.

Facebook Pixel

Tag în GTM: Tags → New → Custom HTML.

<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 + condiție dlv.cp_marketing equals true.
  • Tag firing options: Once per page.

Opțional, pentru conformitate deplină cu Facebook Limited Data Use, adaugă un al doilea tag care apelează fbq('consent','revoke') cu triggerul dlv.cp_marketing equals false.

TikTok Pixel

Tag în GTM: Tags → New → Custom HTML.

<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 + condiție dlv.cp_marketing equals true.
  • Tag firing options: Once per page.

ttq.grantConsent() este noul API TikTok (din 2024). Fără el, TikTok primește date hashuite fără consimțământ, ceea ce încalcă termenii.

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 + condiție dlv.cp_marketing equals true.
  • Tag firing options: Once per page.

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 + condiție dlv.cp_analytics equals true.
  • Tag firing options: Once per page.

Hotjar intră la analytics, nu la marketing (măsoară comportamentul, nu reclamele). Verifică propria politică de cookie-uri, unele companii clasifică Hotjar diferit.

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 + condiție dlv.cp_analytics equals true.
  • Tag firing options: Once per page.

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 + condiție dlv.cp_marketing equals true.
  • Tag firing options: Once per page.

Microsoft Ads (UET)

UET acceptă Google Consent Mode din finalul lui 2023, deci nu ai nevoie de un trigger Custom Event. Inserează tagul în mod standard (All Pages, Once per page), iar UET citește singur ad_storage din GCM, pe care îl setează widgetul.

Maparea categoriilor (pe scurt)

TagCategorieCâmp în cookiepilot_consent
Facebook Pixelmarketingmarketing
TikTok Pixelmarketingmarketing
LinkedIn Insightmarketingmarketing
Pinterestmarketingmarketing
Hotjaranalyticsanalytics
Microsoft Clarityanalyticsanalytics
Mixpanel, Amplitudeanalyticsanalytics
Intercom, Drift, Crisppreferencespreferences
GA4, Google Ads, UET(GCM, fără trigger)gestionat prin gtag('consent','update')

API Reference

CookiePilot expune obiectul window.CookiePilot:

MetodăDescriere
CookiePilot.getConsent()Starea curentă a consimțămintelor sau null dacă nu există nicio decizie.
CookiePilot.acceptAll()Consimțământ pentru toate categoriile.
CookiePilot.rejectAll()Respinge tot, în afară de necessary.
CookiePilot.updateConsent(partial)Actualizează categoriile selectate, de ex. { analytics: true }.
CookiePilot.showSettings()Deschide modalul de preferințe.
CookiePilot.hideSettings()Închide modalul de preferințe.
CookiePilot.showMyConsent() / hideMyConsent()Afișează/ascunde butonul plutitor.

Exemplu

const consent = CookiePilot.getConsent();
// { necessary: true, analytics: true, marketing: false, preferences: false }

CookiePilot.updateConsent({ analytics: true });

document.getElementById('cookie-settings').addEventListener('click', () => {
  CookiePilot.showSettings();
});
<a href="#" onclick="CookiePilot.showSettings(); return false;">Gestionează cookie-urile</a>

Evenimente JavaScript

Widgetul emite (dispatch) un eveniment nativ cookiepilot:consent pe window. Listenerul trebuie înregistrat înainte de încărcarea widgetului, dacă vrei să prinzi evenimentul pentru un utilizator care revine (dispatch-ul se trimite imediat după pornirea widgetului):

<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 conține același payload ca getConsent(). Pentru integrarea prin GTM folosește în locul lui evenimentul din dataLayer descris mai sus, deoarece dataLayer este un array persistent, iar GTM preia și evenimentele istorice.


Categorii de consimțământ

CategorieDescriereImplicit
necessaryNecesare pentru funcționarea site-uluiÎntotdeauna active
analyticsStatistici și analizăNecesită consimțământ
marketingReclame și remarketingNecesită consimțământ
preferencesPersonalizare, limbăNecesită consimțământ
Categorie CookiePilotCâmpuri Consent Mode
analyticsanalytics_storage
marketingad_storage, ad_user_data, ad_personalization
preferencesfunctionality_storage, personalization_storage
(întotdeauna)security_storage: granted

Versiunea 2 a adăugat ad_user_data și ad_personalization (obligatorii din martie 2024 pentru UE/SEE în cazul reclamelor Google).

ParametruDescriere
ad_storageCookie-uri de publicitate
analytics_storageCookie-uri de analiză
ad_user_dataTrimiterea datelor utilizatorului către Google
ad_personalizationPersonalizarea reclamelor
functionality_storageCookie-uri funcționale
personalization_storageCookie-uri de personalizare
security_storageÎntotdeauna granted

Mecanism:

  1. Stub-ul setează sincron toate câmpurile pe denied, cu wait_for_update: 500.
  2. După decizia utilizatorului, widgetul trimite gtag('consent', 'update', {...}) cu maparea de mai sus.
  3. Pentru un utilizator care revine, punctul 2 se trimite imediat după pornirea widgetului, pe baza cookie-ului.

Configurarea aspectului

În panou: Domeniu → Configurare:

  • Aspect: poziție, culori, layout (BAR / BOX / MODAL).
  • Texte: titlu, descriere, etichetele butoanelor, descrierile categoriilor. 13 limbi (EN, PL, DE, FR, ES, IT, NL, PT, SV, CS, RO, EL, HU).
  • Buton de consimțământ: butonul plutitor „Setări cookie-uri” vizibil după prima decizie (stânga/dreapta jos).
  • Custom CSS: câmp pentru stiluri proprii. Widgetul se randează în Shadow DOM, așa că selectorii CSS din documentul principal nu vor funcționa. Doar prin acest câmp.

Accesibilitate (WCAG 2.1 AA)

  • ✅ Navigare cu tastatura (Tab, Shift+Tab, Enter, Escape).
  • ✅ ARIA labels, role="dialog", aria-modal.
  • ✅ Focus trap în modal.
  • ✅ Cititor de ecran (live regions la schimbarea stării).
  • ✅ Responsivitate.

Integrări

WordPress

Avem un plugin oficial: CookiePilot pe WordPress.org.

  1. WordPress admin → Plugin-uri → Adaugă nou → caută „CookiePilot”.
  2. Instalează și activează.
  3. Setări → CookiePilot → inserează cheia API din panou.

Pluginul inserează singur stub-ul și tagul în <head> (cu ordinea corectă, înaintea celorlalte scripturi) și pune la dispoziție shortcode-ul [cookiepilot_settings] pentru linkul „Gestionează cookie-urile” din subsol.

Dacă preferi fără plugin: folosește „Insert Headers and Footers” și inserează snippetul de la pasul 2 din Pornirea rapidă în secțiunea Header.

Shopify

  1. Magazin → Teme → Editează codul.
  2. În theme.liquid inserează snippetul înainte de </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" asigură că scriptul bannerului se execută devreme. Reține că inline stub-ul din Pasul 2a (consimțăminte implicite) îl adaugi separat, în <head>, înaintea acestui script, de ex. prin next/script cu dangerouslySetInnerHTML sau direct în app/layout.tsx.


FAQ

Scriptul încetinește site-ul?

Bundle-ul are cca. 12 KB gzip, încărcat asincron. Fără impact asupra Core Web Vitals.

Cât timp sunt păstrate consimțămintele?

Cookie-ul cu decizia utilizatorului: implicit 365 de zile (configurabil în panou). Evenimentele din analiză: 2 ani (TTL ClickHouse).

Da. Widgetul citește cookie-ul la pornire și trimite evenimentul în dataLayer. Triggerul Custom Event din GTM se va declanșa la fiecare vizită, nu doar la prima decizie.

Unde raportez o problemă?

kontakt@cookiepilot.io sau chatul din panou.


Checklist de testare după implementare

După instalarea CookiePilot, verifică configurarea înainte de a publica campaniile de publicitate.

1. Test înainte de consimțământul utilizatorului

  1. Deschide site-ul în mod incognito și șterge cookie-urile pentru domeniu.
  2. Deschide DevTools → Network și reîmprospătează pagina.
  3. Înainte de a da click pe consimțământ, verifică faptul că:
    • nu se creează cookie-uri de analiză/marketing, de ex. _ga, _gcl_*, _fbp, _ttp,
    • tagurile de marketing nu trimit requesturi către Meta/TikTok/LinkedIn înaintea consimțământului de marketing,
    • în dataLayer este setată starea implicită denied pentru ad_storage, ad_user_data, ad_personalization și analytics_storage.

2. Test după acceptarea consimțămintelor

  1. Dă click pe „Acceptă tot”.
  2. În DevTools verifică dacă a apărut evenimentul cookiepilot_consent_update.
  3. Pentru tagurile Google, verifică în GTM Preview / Tag Assistant dacă Consent Mode a schimbat starea pe granted pentru categoriile corespunzătoare.
  4. Pentru GA4, verifică în DebugView dacă evenimentele au început să sosească după consimțământ.
  5. Pentru Meta Pixel / TikTok / LinkedIn, verifică dacă tagurile se declanșează abia după evenimentul cookiepilot_consent_update și după condiția de consimțământ de marketing.

3. Test de respingere a consimțămintelor

  1. Șterge cookie-urile și reîmprospătează pagina.
  2. Dă click pe „Respinge tot”.
  3. Verifică faptul că cookie-urile și requesturile de marketing tot nu se declanșează.
  4. Verifică faptul că funcțiile necesare ale site-ului funcționează în continuare.

4. Cele mai frecvente greșeli

  • Tagul GA4/Google Ads se declanșează pe Consent Initialization în loc de un trigger ulterior.
  • Meta Pixel sau TikTok Pixel nu are condiție pe cookiepilot_consent.marketing.
  • Pe site a rămas un tracker vechi, hardcodat în <head> înaintea CookiePilot.
  • În documentație sau în șablon a rămas un URL de script neactualizat sau un atribut de identificator vechi în locul actualului cookiepilot.js cu data-cpkey.