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
- Ustvarite račun na app.cookiepilot.io/register.
- 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.
Oznaka: CookiePilot - Consent Init + Banner
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 red | Oznaka | Sprožilec |
|---|---|---|
| 1 | CookiePilot - Consent Init + Banner | Consent Initialization - All Pages |
| 2 | GA4, Google Ads, UET | All Pages (Consent Mode sam obravnava soglasja) |
| 3 | Facebook 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.
- 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). - 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
- Name
- 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+ pogojdlv.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+ pogojdlv.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+ pogojdlv.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+ pogojdlv.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+ pogojdlv.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+ pogojdlv.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)
| Oznaka | Kategorija | Polje v 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, brez sprožilca) | obravnava gtag('consent','update') |
API Reference
CookiePilot izpostavlja objekt window.CookiePilot:
| Metoda | Opis |
|---|---|
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
| Kategorija | Opis | Privzeto |
|---|---|---|
necessary | Nujno za delovanje strani | Vedno aktivno |
analytics | Statistika in analitika | Potrebno soglasje |
marketing | Oglasi in remarketing | Potrebno soglasje |
preferences | Personalizacija, jezik | Potrebno soglasje |
Preslikava na Google Consent Mode
| Kategorija CookiePilot | Polja Consent Mode |
|---|---|
analytics | analytics_storage |
marketing | ad_storage, ad_user_data, ad_personalization |
preferences | functionality_storage, personalization_storage |
| (vedno) | security_storage: granted |
Google Consent Mode v2
Različica 2 je dodala ad_user_data in ad_personalization (obvezna od marca 2024 za EU/EGP pri Googlovem oglaševanju).
| Parameter | Opis |
|---|---|
ad_storage | Oglaševalski piškotki |
analytics_storage | Analitični piškotki |
ad_user_data | Pošiljanje uporabniških podatkov Googlu |
ad_personalization | Personalizacija oglasov |
functionality_storage | Funkcionalni piškotki |
personalization_storage | Personalizacijski piškotki |
security_storage | Vedno granted |
Mehanizem:
- Stub vsa polja sinhrono nastavi na
denied, zwait_for_update: 500. - Po odločitvi uporabnika widget sproži
gtag('consent', 'update', {...})s preslikavo zgoraj. - 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.
- WordPress admin → Vtičniki → Dodaj nov → poiščite "CookiePilot".
- Namestite in aktivirajte.
- 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
- Trgovina → Teme → Uredi kodo.
- V
theme.liquidprilepite 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).
Ali se dogodek cookiepilot_consent_update sproži za vračajočega se uporabnika?
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
- Odprite stran v načinu brez beleženja zgodovine (incognito) in počistite piškotke za domeno.
- Odprite DevTools → Network in osvežite stran.
- 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
dataLayernastavljeno privzeto stanjedeniedzaad_storage,ad_user_data,ad_personalizationinanalytics_storage.
- ne nastajajo analitični/marketinški piškotki, npr.
2. Test po sprejemu soglasij
- Kliknite »Sprejmi vse«.
- V DevTools preverite, ali se je pojavil dogodek
cookiepilot_consent_update. - Za Googlove oznake v GTM Preview / Tag Assistant preverite, ali je Consent Mode stanje spremenil na
grantedza ustrezne kategorije. - Za GA4 v DebugView preverite, ali so dogodki začeli prihajati po soglasju.
- Za Meta Pixel / TikTok / LinkedIn preverite, ali se oznake sprožijo šele po dogodku
cookiepilot_consent_updatein pogoju marketinškega soglasja.
3. Test zavrnitve soglasij
- Počistite piškotke in osvežite stran.
- Kliknite »Zavrni vse«.
- Preverite, da se marketinški piškotki in zahtevki še naprej ne sprožajo.
- Preverite, da nujne funkcije strani še naprej delujejo.
4. Najpogostejše napake
- Oznaka GA4/Google Ads se sproži na
Consent Initializationnamesto 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.jszdata-cpkey.