Dokumentacija

Dokumentacija za razvijalce

CookiePilot je platforma za upravljanje soglasij za piškotke (CMP), skladna z GDPR, ZEKom-2 in Google Consent Mode v2.

Uvod

CookiePilot je platforma za upravljanje soglasij za piškotke (CMP), skladna s Splošno uredbo o varstvu podatkov (GDPR), slovenskim zakonom o e-zasebnosti (Zakon o elektronskih komunikacijah, ZEKom-2) in Google Consent Mode v2. Spoštovanje teh predpisov v Sloveniji nadzira Informacijski pooblaščenec (IP-RS).

Komu je namenjen

  • Lastniki spletnih strani: uvedba brez programiranja.
  • Razvijalci: API, dogodki, integracije z GTM.
  • Agencije: white-label, upravljanje več domen.

Hitri začetek

Korak 1: Registracija

  1. Ustvarite račun na app.cookiepilot.io/register.
  2. Dodajte domeno v nadzorni plošči in kopirajte API-ključ (oblika cp_live_...).

Korak 2: Namestitev kode

Neposredna namestitev sta dve skripti v razdelku <head>, v tem vrstnem redu.

Korak 2a: Privzeta soglasja (inline stub). Prilepite ga kot prvega, pred katero koli drugo skripto (cookiepilot.js, GA, GTM, oglaševalske in sledilne oznake):

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

Ta inline izrezek vse kategorije takoj nastavi na denied (z wait_for_update: 500), zato je privzeto stanje Google Consent Mode v2 pripravljeno, preden se naloži karkoli drugega. Pri vračajočem se uporabniku takoj prebere shranjeno soglasje iz piškotka in sproži consent update.

Korak 2b: Skripta pasice. Dodajte jo takoj za inline stubom:

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

Korak 3: Konfiguracija pasice

V nadzorni plošči: Domena → Konfiguracija → Videz:

  • položaj pasice (zgoraj, spodaj, modalno okno),
  • barve in besedila,
  • plavajoči gumb "Nastavitve piškotkov" za vračajoče se uporabnike.

Integracija z Google Tag Managerjem

Prek GTM namestite CookiePilot z eno oznako Custom HTML, ki takoj nastavi privzeta soglasja in naloži pasico v najzgodnejši fazi GTM. Ne potrebujete ločene datoteke stub niti druge oznake.

V GTM ustvarite oznako Custom HTML (Oznake → Nova → Custom HTML) in prilepite:

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

Sprožilec: Consent Initialization - All Pages. Oznaka se mora sprožiti enkrat na stran. Googlove oznake (GA4, Google Ads), Facebook Pixel in druge marketinške oznake NE uporabljajo sprožilca Consent Initialization, temveč se sprožijo pozneje (Consent Checks ali sprožilec, odvisen od soglasja). Shranite oznako in objavite vsebnik GTM.

Vrstni red in sprožilci

Vrstni redOznakaSprožilec
1CookiePilot - Consent Init + BannerConsent Initialization - All Pages
2GA4, Google Ads, UETAll Pages (Consent Mode sam obravnava soglasja)
3Facebook Pixel, TikTok, LinkedIn itd.Custom Event cookiepilot_consent_update + pogoj soglasja (glejte spodaj)

Oznake zunaj Googla (Facebook Pixel, TikTok, LinkedIn)

Google Consent Mode obravnava le Googlove oznake. Za preostale skripte widget ob vsaki spremembi soglasja v dataLayer potisne dogodek:

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

Dogodek se sproži tudi ob vsakem obisku vračajočega se uporabnika (ko widget prebere piškotek s soglasjem), zato se sprožilec v GTM aktivira ob vsakem obisku, ne le ob prvi odločitvi.

Skupni vzorec (izvedite enkrat)

Te tri elemente konfigurirate enkrat, nato jih uporabljate za vse oznake zunaj Googla.

  1. Sprožilec (Triggers → New → Custom Event): ime dogodka cookiepilot_consent_update. Brez pogojev, brez "Once per page" (oznaka se mora znova sprožiti po spremembi odločitve).
  2. Data Layer Variable za vsako kategorijo, ki jo uporabljate:
    • Name cookiepilot_consent.marketing → spremenljivka npr. dlv.cp_marketing
    • Name cookiepilot_consent.analytics → spremenljivka npr. dlv.cp_analytics
    • Name cookiepilot_consent.preferences → spremenljivka npr. dlv.cp_preferences
  3. Trigger Group ali pogoj v sprožilcu: dlv.cp_marketing equals true (za marketinške oznake) ali ustrezno polje.

V vsakem od spodnjih primerov je Trigger isti Custom Event z dodanim pogojem na ustrezno spremenljivko.

Facebook Pixel

Oznaka v 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>
  • Sprožilec: cookiepilot_consent_update + pogoj dlv.cp_marketing equals true.
  • Tag firing options: Once per page.

Po želji za polno skladnost s Facebook Limited Data Use dodajte drugo oznako, ki kliče fbq('consent','revoke') s sprožilcem dlv.cp_marketing equals false.

TikTok Pixel

Oznaka v 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>
  • Sprožilec: cookiepilot_consent_update + pogoj dlv.cp_marketing equals true.
  • Tag firing options: Once per page.

ttq.grantConsent() je novi API TikToka (od leta 2024). Brez njega TikTok prejme zgoščene podatke brez soglasja, kar krši pogoje.

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>
  • Sprožilec: cookiepilot_consent_update + pogoj 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>
  • Sprožilec: cookiepilot_consent_update + pogoj dlv.cp_analytics equals true.
  • Tag firing options: Once per page.

Hotjar sodi pod analytics, ne marketing (meri vedenje, ne oglasov). Preverite svojo politiko piškotkov, saj nekatera podjetja Hotjar uvrščajo drugače.

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>
  • Sprožilec: cookiepilot_consent_update + pogoj 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>
  • Sprožilec: cookiepilot_consent_update + pogoj dlv.cp_marketing equals true.
  • Tag firing options: Once per page.

Microsoft Ads (UET)

UET podpira Google Consent Mode od konca leta 2023, zato ne potrebujete sprožilca Custom Event. Oznako vstavite na običajen način (All Pages, Once per page), UET pa sam prebere ad_storage iz GCM, ki ga nastavi widget.

Preslikava kategorij (povzetek)

OznakaKategorijaPolje v cookiepilot_consent
Facebook Pixelmarketingmarketing
TikTok Pixelmarketingmarketing
LinkedIn Insightmarketingmarketing
Pinterestmarketingmarketing
Hotjaranalyticsanalytics
Microsoft Clarityanalyticsanalytics
Mixpanel, Amplitudeanalyticsanalytics
Intercom, Drift, Crisppreferencespreferences
GA4, Google Ads, UET(GCM, brez sprožilca)obravnava gtag('consent','update')

API Reference

CookiePilot izpostavlja objekt window.CookiePilot:

MetodaOpis
CookiePilot.getConsent()Trenutno stanje soglasij ali null, če odločitve ni.
CookiePilot.acceptAll()Soglasje za vse kategorije.
CookiePilot.rejectAll()Zavrne vse razen necessary.
CookiePilot.updateConsent(partial)Posodobi izbrane kategorije, npr. { analytics: true }.
CookiePilot.showSettings()Odpre modalno okno preferenc.
CookiePilot.hideSettings()Zapre modalno okno preferenc.
CookiePilot.showMyConsent() / hideMyConsent()Prikaže/skrije plavajoči gumb.

Primer

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

CookiePilot.updateConsent({ analytics: true });

document.getElementById('cookie-settings').addEventListener('click', () => {
  CookiePilot.showSettings();
});

Povezava "Upravljaj piškotke" v nogi

<a href="#" onclick="CookiePilot.showSettings(); return false;">Upravljaj piškotke</a>

Dogodki JavaScript

Widget na window sproži (dispatch) izvorni dogodek cookiepilot:consent. Poslušalec (listener) mora biti registriran pred nalaganjem widgeta, če želite ujeti dogodek za vračajočega se uporabnika (dispatch se sproži takoj po zagonu widgeta):

<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 vsebuje enak payload kot getConsent(). Za integracijo prek GTM namesto tega uporabite dogodek dataLayer, opisan zgoraj, saj je dataLayer persistent array in GTM upošteva tudi pretekle dogodke.


Kategorije soglasij

KategorijaOpisPrivzeto
necessaryNujno za delovanje straniVedno aktivno
analyticsStatistika in analitikaPotrebno soglasje
marketingOglasi in remarketingPotrebno soglasje
preferencesPersonalizacija, jezikPotrebno soglasje
Kategorija CookiePilotPolja Consent Mode
analyticsanalytics_storage
marketingad_storage, ad_user_data, ad_personalization
preferencesfunctionality_storage, personalization_storage
(vedno)security_storage: granted

Različica 2 je dodala ad_user_data in ad_personalization (obvezna od marca 2024 za EU/EGP pri Googlovem oglaševanju).

ParameterOpis
ad_storageOglaševalski piškotki
analytics_storageAnalitični piškotki
ad_user_dataPošiljanje uporabniških podatkov Googlu
ad_personalizationPersonalizacija oglasov
functionality_storageFunkcionalni piškotki
personalization_storagePersonalizacijski piškotki
security_storageVedno granted

Mehanizem:

  1. Stub vsa polja sinhrono nastavi na denied, z wait_for_update: 500.
  2. Po odločitvi uporabnika widget sproži gtag('consent', 'update', {...}) s preslikavo zgoraj.
  3. Pri vračajočem se uporabniku se točka 2 sproži takoj po zagonu widgeta, na podlagi piškotka.

Konfiguracija videza

V nadzorni plošči: Domena → Konfiguracija:

  • Videz: položaj, barve, postavitev (BAR / BOX / MODAL).
  • Besedila: naslov, opis, oznake gumbov, opisi kategorij. 13 jezikov (EN, PL, DE, FR, ES, IT, NL, PT, SV, CS, RO, EL, HU).
  • Gumb za soglasja: plavajoči gumb "Nastavitve piškotkov", viden po prvi odločitvi (spodaj levo/desno).
  • Custom CSS: polje za lastne sloge. Widget se izriše v Shadow DOM, zato selektorji CSS iz glavnega dokumenta ne delujejo. Samo prek tega polja.

Dostopnost (WCAG 2.1 AA)

  • ✅ Navigacija s tipkovnico (Tab, Shift+Tab, Enter, Escape).
  • ✅ ARIA labels, role="dialog", aria-modal.
  • ✅ Focus trap v modalnem oknu.
  • ✅ Bralnik zaslona (live regions ob spremembi stanja).
  • ✅ Odzivnost.

Integracije

WordPress

Imamo uradni vtičnik: CookiePilot na WordPress.org.

  1. WordPress admin → Vtičniki → Dodaj nov → poiščite "CookiePilot".
  2. Namestite in aktivirajte.
  3. Nastavitve → CookiePilot → prilepite API-ključ iz nadzorne plošče.

Vtičnik samodejno vstavi stub in oznako v <head> (s pravilnim vrstnim redom pred drugimi skriptami) ter ponudi shortcode [cookiepilot_settings] za povezavo "Upravljaj piškotke" v nogi.

Če imate raje brez vtičnika: uporabite "Insert Headers and Footers" in prilepite izrezek iz koraka 2 Hitrega začetka v razdelek Header.

Shopify

  1. Trgovina → Teme → Uredi kodo.
  2. V theme.liquid prilepite izrezek pred </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" poskrbi, da se skripta pasice izvede zgodaj. Ne pozabite, da inline stub iz Koraka 2a (privzeta soglasja) dodate ločeno, v <head> pred to skripto, npr. prek next/script z dangerouslySetInnerHTML ali neposredno v app/layout.tsx.


Pogosta vprašanja

Ali skripta upočasni stran?

Bundle je velik približno 12 KB gzip in se nalaga asinhrono. Brez vpliva na Core Web Vitals.

Kako dolgo se hranijo soglasja?

Piškotek z odločitvijo uporabnika: privzeto 365 dni (nastavljivo v nadzorni plošči). Dogodki v analitiki: 2 leti (TTL ClickHouse).

Da. Widget ob zagonu prebere piškotek in potisne dogodek v dataLayer. Sprožilec Custom Event v GTM se aktivira ob vsakem obisku, ne le ob prvi odločitvi.

Kje prijavim težavo?

kontakt@cookiepilot.io ali klepet v nadzorni plošči.


Kontrolni seznam za preizkus po uvedbi

Po namestitvi CookiePilota preverite konfiguracijo, preden objavite oglaševalske kampanje.

1. Test pred soglasjem uporabnika

  1. Odprite stran v načinu brez beleženja zgodovine (incognito) in počistite piškotke za domeno.
  2. Odprite DevTools → Network in osvežite stran.
  3. Pred klikom na soglasje preverite, da:
    • ne nastajajo analitični/marketinški piškotki, npr. _ga, _gcl_*, _fbp, _ttp,
    • marketinške oznake pred marketinškim soglasjem ne pošiljajo zahtevkov k Meti/TikToku/LinkedInu,
    • je v dataLayer nastavljeno privzeto stanje denied za ad_storage, ad_user_data, ad_personalization in analytics_storage.

2. Test po sprejemu soglasij

  1. Kliknite »Sprejmi vse«.
  2. V DevTools preverite, ali se je pojavil dogodek cookiepilot_consent_update.
  3. Za Googlove oznake v GTM Preview / Tag Assistant preverite, ali je Consent Mode stanje spremenil na granted za ustrezne kategorije.
  4. Za GA4 v DebugView preverite, ali so dogodki začeli prihajati po soglasju.
  5. Za Meta Pixel / TikTok / LinkedIn preverite, ali se oznake sprožijo šele po dogodku cookiepilot_consent_update in pogoju marketinškega soglasja.

3. Test zavrnitve soglasij

  1. Počistite piškotke in osvežite stran.
  2. Kliknite »Zavrni vse«.
  3. Preverite, da se marketinški piškotki in zahtevki še naprej ne sprožajo.
  4. Preverite, da nujne funkcije strani še naprej delujejo.

4. Najpogostejše napake

  • Oznaka GA4/Google Ads se sproži na Consent Initialization namesto na poznejšem sprožilcu.
  • Meta Pixel ali TikTok Pixel nima pogoja na cookiepilot_consent.marketing.
  • Na strani je ostal star, trdo zakodiran sledilnik v <head> pred CookiePilotom.
  • V dokumentaciji ali predlogi je ostal zastarel URL skripte ali star atribut identifikatorja namesto aktualnega cookiepilot.js z data-cpkey.