Dokumentacja

Dokumentacja CookiePilot

Kompletny przewodnik po instalacji, konfiguracji i integracji CookiePilot z Twoją stroną.

Wprowadzenie

CookiePilot to platforma do zarządzania zgodami cookies (CMP), zgodna z RODO, PKE i Google Consent Mode v2.

Dla kogo

  • Właściciele stron: wdrożenie bez programowania.
  • Developerzy: API, eventy, integracje z GTM.
  • Agencje: white-label, zarządzanie wieloma domenami.

Szybki start

Krok 1: Rejestracja

  1. Załóż konto na app.cookiepilot.io/register.
  2. Dodaj domenę w panelu i skopiuj klucz API (format cp_live_...).

Krok 2: Instalacja kodu

Instalacja bezpośrednia to dwa skrypty w sekcji <head>, w tej kolejności.

Krok 2a: Domyślne zgody (inline stub). Wklej jako pierwszy, przed jakimkolwiek innym skryptem (cookiepilot.js, GA, GTM, tagi reklamowe i trackujące):

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

Ten inline snippet od razu ustawia wszystkie kategorie na denied (z wait_for_update: 500), więc domyślny stan Google Consent Mode v2 jest gotowy zanim cokolwiek innego się załaduje. Dla powracającego użytkownika od razu odczytuje zapisaną zgodę z cookie i puszcza consent update.

Krok 2b: Skrypt banera. Dodaj zaraz po inline stubie:

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

Krok 3: Konfiguracja banera

W panelu: Domena → Konfiguracja → Wygląd:

  • pozycja banera (góra, dół, modal),
  • kolory i teksty,
  • pływający przycisk "Ustawienia cookies" dla powracających użytkowników.

Integracja z Google Tag Manager

Przez GTM instalujesz CookiePilot jednym tagiem Custom HTML, który od razu ustawia domyślne zgody i ładuje baner w najwcześniejszej fazie GTM. Nie potrzebujesz osobnego pliku stub ani drugiego tagu.

W GTM utwórz tag Custom HTML (Tagi → Nowy → Niestandardowy kod HTML) i wklej:

<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. Tag musi uruchamiać się raz na stronę. Tagi Google (GA4, Google Ads), Facebook Pixel i inne tagi marketingowe NIE używają triggera Consent Initialization, tylko odpalają się później (Consent Checks albo trigger zależny od zgody). Zapisz tag i opublikuj kontener GTM.

Kolejność i triggery

KolejnośćTagTrigger
1CookiePilot - Consent Init + BannerConsent Initialization - All Pages
2GA4, Google Ads, UETAll Pages (Consent Mode sam obsłuży zgody)
3Facebook Pixel, TikTok, LinkedIn itd.Custom Event cookiepilot_consent_update + warunek zgody (patrz niżej)

Tagi spoza Google (Facebook Pixel, TikTok, LinkedIn)

Google Consent Mode obsługuje tylko tagi Google. Dla pozostałych skryptów widget przy każdej zmianie zgody pushuje do dataLayer event:

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

Event leci również przy każdym wejściu powracającego użytkownika (gdy widget odczyta cookie ze zgodą), więc trigger w GTM zadziała na każdej wizycie, nie tylko przy pierwszej decyzji.

Wspólny pattern (wykonaj raz)

Te trzy elementy konfigurujesz raz, potem używasz dla wszystkich tagów spoza Google.

  1. Trigger (Triggers → New → Custom Event): Event name cookiepilot_consent_update. Bez warunków, bez "Once per page" (tag musi móc odpalić się ponownie po zmianie decyzji).
  2. Data Layer Variable dla każdej kategorii której używasz:
    • Name cookiepilot_consent.marketing → zmienna np. dlv.cp_marketing
    • Name cookiepilot_consent.analytics → zmienna np. dlv.cp_analytics
    • Name cookiepilot_consent.preferences → zmienna np. dlv.cp_preferences
  3. Trigger Group lub warunek w triggerze: dlv.cp_marketing equals true (dla tagów marketingowych) albo odpowiednie pole.

W każdym z poniższych przykładów Trigger to ten sam Custom Event z dorzuconym warunkiem na właściwą zmienną.

Facebook Pixel

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

Opcjonalnie, dla pełnej zgodności z Facebook Limited Data Use, dodaj drugi tag wywołujący fbq('consent','revoke') z triggerem dlv.cp_marketing equals false.

TikTok Pixel

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

ttq.grantConsent() to nowe API TikTok (od 2024). Bez tego TikTok dostaje hashowane dane bez zgody, co łamie warunki.

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

Hotjar idzie pod analytics, nie marketing (mierzy zachowanie, nie reklamy). Sprawdź własną politykę cookies, niektóre firmy klasyfikują Hotjar inaczej.

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

Microsoft Ads (UET)

UET wspiera Google Consent Mode od końca 2023, więc nie potrzebujesz Custom Event triggera. Wstaw tag standardowo (All Pages, Once per page), a UET sam czyta ad_storage z GCM, które ustawia widget.

Mapowanie kategorii (skrót)

TagKategoriaPole w cookiepilot_consent
Facebook Pixelmarketingmarketing
TikTok Pixelmarketingmarketing
LinkedIn Insightmarketingmarketing
Pinterestmarketingmarketing
Hotjaranalyticsanalytics
Microsoft Clarityanalyticsanalytics
Mixpanel, Amplitudeanalyticsanalytics
Intercom, Drift, Crisppreferencespreferences
GA4, Google Ads, UET(GCM, bez triggera)obsługiwane przez gtag('consent','update')

API Reference

CookiePilot udostępnia obiekt window.CookiePilot:

MetodaOpis
CookiePilot.getConsent()Aktualny stan zgód lub null jeśli nie ma decyzji.
CookiePilot.acceptAll()Zgoda na wszystkie kategorie.
CookiePilot.rejectAll()Odrzuca wszystko poza necessary.
CookiePilot.updateConsent(partial)Aktualizuje wybrane kategorie, np. { analytics: true }.
CookiePilot.showSettings()Otwiera modal preferencji.
CookiePilot.hideSettings()Zamyka modal preferencji.
CookiePilot.showMyConsent() / hideMyConsent()Pokazuje/ukrywa pływający przycisk.

Przykład

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;">Zarządzaj cookies</a>

Eventy JavaScript

Widget dispatcuje natywny event cookiepilot:consent na window. Listener musi być zarejestrowany przed załadowaniem widgetu, jeśli chcesz złapać event dla powracającego użytkownika (dispatch leci natychmiast po starcie widgetu):

<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 zawiera ten sam payload co getConsent(). Dla integracji przez GTM użyj dataLayer eventu opisanego wyżej zamiast tego, bo dataLayer jest persistent array i GTM łyka eventy historyczne.


Kategorie zgód

KategoriaOpisDomyślnie
necessaryNiezbędne do działania stronyZawsze aktywne
analyticsStatystyki i analitykaWymagana zgoda
marketingReklamy i remarketingWymagana zgoda
preferencesPersonalizacja, językWymagana zgoda
Kategoria CookiePilotPola Consent Mode
analyticsanalytics_storage
marketingad_storage, ad_user_data, ad_personalization
preferencesfunctionality_storage, personalization_storage
(zawsze)security_storage: granted

Wersja 2 dodała ad_user_data i ad_personalization (wymagane od marca 2024 dla EU/EEA przy reklamach Google).

ParametrOpis
ad_storageCookies reklamowe
analytics_storageCookies analityczne
ad_user_dataWysyłka danych użytkownika do Google
ad_personalizationPersonalizacja reklam
functionality_storageCookies funkcjonalne
personalization_storageCookies personalizacyjne
security_storageZawsze granted

Mechanizm:

  1. Stub ustawia wszystkie pola na denied synchronicznie, z wait_for_update: 500.
  2. Po decyzji użytkownika widget puszcza gtag('consent', 'update', {...}) z mapowaniem powyżej.
  3. Dla powracającego użytkownika punkt 2 leci natychmiast po starcie widgetu, na podstawie cookie.

Konfiguracja wyglądu

W panelu: Domena → Konfiguracja:

  • Wygląd: pozycja, kolory, układ (BAR / BOX / MODAL).
  • Teksty: nagłówek, opis, etykiety przycisków, opisy kategorii. 13 języków (EN, PL, DE, FR, ES, IT, NL, PT, SV, CS, RO, EL, HU).
  • Przycisk zgód: pływający przycisk "Ustawienia cookies" widoczny po pierwszej decyzji (lewy/prawy dół).
  • Custom CSS: pole na własne style. Widget renderuje się w Shadow DOM, więc selektory CSS z głównego dokumentu nie zadziałają. Tylko przez to pole.

Dostępność (WCAG 2.1 AA)

  • ✅ Nawigacja klawiaturą (Tab, Shift+Tab, Enter, Escape).
  • ✅ ARIA labels, role="dialog", aria-modal.
  • ✅ Focus trap w modalu.
  • ✅ Screen reader (live regions na zmianę stanu).
  • ✅ Responsywność.

Integracje

WordPress

Mamy oficjalną wtyczkę: CookiePilot na WordPress.org.

  1. WordPress admin → Wtyczki → Dodaj nową → szukaj "CookiePilot".
  2. Zainstaluj i aktywuj.
  3. Ustawienia → CookiePilot → wklej klucz API z panelu.

Wtyczka sama wstawia stub i tag w <head> (z poprawną kolejnością przed innymi skryptami) i wystawia shortcode [cookiepilot_settings] do linku "Zarządzaj cookies" w stopce.

Jeśli wolisz bez wtyczki: użyj "Insert Headers and Footers" i wklej snippet z kroku 2 Szybkiego startu w sekcję Header.

Shopify

  1. Sklep → Motywy → Edytuj kod.
  2. W theme.liquid wklej snippet przed </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" zapewnia, że skrypt banera wykona się wcześnie. Pamiętaj, że inline stub z Kroku 2a (domyślne zgody) dodajesz osobno, w <head> przed tym skryptem, np. przez next/script z dangerouslySetInnerHTML albo bezpośrednio w app/layout.tsx.


FAQ

Czy skrypt spowalnia stronę?

Bundle to ok. 12 KB gzip, ładowany asynchronicznie. Bez wpływu na Core Web Vitals.

Jak długo trzymane są zgody?

Cookie z decyzją użytkownika: domyślnie 365 dni (konfigurowalne w panelu). Zdarzenia w analityce: 2 lata (TTL ClickHouse).

Tak. Widget odczytuje cookie przy starcie i pushuje event do dataLayer. Trigger Custom Event w GTM odpali się przy każdej wizycie, nie tylko przy pierwszej decyzji.

Gdzie zgłosić problem?

kontakt@cookiepilot.io lub chat w panelu.