Úvod
CookiePilot je platforma pro správu souhlasů s cookies (CMP), která je v souladu s GDPR (obecné nařízení o ochraně osobních údajů), českým zákonem č. 127/2005 Sb., o elektronických komunikacích, a s Google Consent Mode v2. Dodržování těchto předpisů v Česku vymáhá Úřad pro ochranu osobních údajů (ÚOOÚ).
Pro koho
- Majitelé webů: nasazení bez programování.
- Vývojáři: API, eventy, integrace s GTM.
- Agentury: white-label, správa více domén.
Rychlý start
Krok 1: Registrace
- Založte si účet na app.cookiepilot.io/register.
- Přidejte doménu v panelu a zkopírujte API klíč (formát
cp_live_...).
Krok 2: Instalace kódu
Přímá instalace znamená dva skripty v sekci <head>, a to v tomto pořadí.
Krok 2a: Výchozí souhlasy (inline stub). Vložte jako první, před jakýkoli jiný skript (cookiepilot.js, GA, GTM, reklamní a sledovací tagy):
<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>
Tento inline snippet okamžitě nastaví všechny kategorie na denied (s wait_for_update: 500), takže výchozí stav Google Consent Mode v2 je připraven dříve, než se cokoli jiného načte. U vracejícího se uživatele ihned načte uložený souhlas z cookie a odešle consent update.
Krok 2b: Skript banneru. Přidejte hned za inline stub:
<!-- CookiePilot -->
<script async src="https://cdn.cookiepilot.io/cookiepilot.js" data-cpkey="TWOJ_KLUCZ"></script>
Krok 3: Konfigurace banneru
V panelu: Doména → Konfigurace → Vzhled:
- pozice banneru (nahoře, dole, modal),
- barvy a texty,
- plovoucí tlačítko „Nastavení cookies“ pro vracející se uživatele.
Integrace s Google Tag Managerem
Přes GTM instalujete CookiePilot jedním tagem Custom HTML, který hned nastaví výchozí souhlasy a načte banner v nejranější fázi GTM. Nepotřebujete samostatný stub ani druhý tag.
Tag: CookiePilot - Consent Init + Banner
V GTM vytvořte tag Custom HTML (Tagy → Nový → Vlastní kód HTML) a vložte:
<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 se musí spustit jednou na stránku. Tagy Google (GA4, Google Ads), Facebook Pixel a další marketingové tagy trigger Consent Initialization NEpoužívají, ale spouštějí se až později (Consent Checks nebo trigger závislý na souhlasu). Uložte tag a publikujte kontejner GTM.
Pořadí a triggery
| Pořadí | Tag | Trigger |
|---|---|---|
| 1 | CookiePilot - Consent Init + Banner | Consent Initialization - All Pages |
| 2 | GA4, Google Ads, UET | All Pages (Consent Mode sám souhlasy obslouží) |
| 3 | Facebook Pixel, TikTok, LinkedIn atd. | Custom Event cookiepilot_consent_update + podmínka souhlasu (viz níže) |
Tagy mimo Google (Facebook Pixel, TikTok, LinkedIn)
Google Consent Mode obsluhuje pouze tagy Google. Pro ostatní skripty widget při každé změně souhlasu pushuje do dataLayer event:
dataLayer.push({
event: 'cookiepilot_consent_update',
cookiepilot_consent: {
necessary: true,
analytics: true,
marketing: true,
preferences: false
}
});
Event se odešle také při každém příchodu vracejícího se uživatele (jakmile widget načte cookie se souhlasem), takže trigger v GTM se spustí při každé návštěvě, nejen při prvním rozhodnutí.
Společný postup (proveďte jednou)
Tyto tři prvky nastavíte jednou a poté je použijete pro všechny tagy mimo Google.
- Trigger (Triggers → New → Custom Event): Event name
cookiepilot_consent_update. Bez podmínek, bez „Once per page“ (tag se musí znovu spustit po změně rozhodnutí). - Data Layer Variable pro každou kategorii, kterou používáte:
- Name
cookiepilot_consent.marketing→ proměnná např.dlv.cp_marketing - Name
cookiepilot_consent.analytics→ proměnná např.dlv.cp_analytics - Name
cookiepilot_consent.preferences→ proměnná např.dlv.cp_preferences
- Name
- Trigger Group nebo podmínka v triggeru:
dlv.cp_marketing equals true(pro marketingové tagy) nebo příslušné pole.
V každém z následujících příkladů je Trigger ten samý Custom Event s přidanou podmínkou na správnou proměnnou.
Facebook Pixel
Tag 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>
- Trigger:
cookiepilot_consent_update+ podmínkadlv.cp_marketing equals true. - Tag firing options: Once per page.
Volitelně, pro plný soulad s Facebook Limited Data Use, přidejte druhý tag volající fbq('consent','revoke') s triggerem dlv.cp_marketing equals false.
TikTok Pixel
Tag 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>
- Trigger:
cookiepilot_consent_update+ podmínkadlv.cp_marketing equals true. - Tag firing options: Once per page.
ttq.grantConsent() je nové API TikTok (od roku 2024). Bez něj TikTok dostává hashovaná data bez souhlasu, což porušuje podmínky.
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+ podmínkadlv.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+ podmínkadlv.cp_analytics equals true. - Tag firing options: Once per page.
Hotjar spadá pod analytics, nikoli marketing (měří chování, ne reklamy). Ověřte si vlastní zásady cookies, některé firmy klasifikují Hotjar jinak.
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+ podmínkadlv.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+ podmínkadlv.cp_marketing equals true. - Tag firing options: Once per page.
Microsoft Ads (UET)
UET podporuje Google Consent Mode od konce roku 2023, takže Custom Event trigger nepotřebujete. Vložte tag standardně (All Pages, Once per page) a UET sám načte ad_storage z GCM, které nastaví widget.
Mapování kategorií (přehled)
| Tag | Kategorie | Pole 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, bez triggeru) | obsluhováno přes gtag('consent','update') |
API Reference
CookiePilot poskytuje objekt window.CookiePilot:
| Metoda | Popis |
|---|---|
CookiePilot.getConsent() | Aktuální stav souhlasů nebo null, pokud rozhodnutí neexistuje. |
CookiePilot.acceptAll() | Souhlas se všemi kategoriemi. |
CookiePilot.rejectAll() | Odmítne vše kromě necessary. |
CookiePilot.updateConsent(partial) | Aktualizuje vybrané kategorie, např. { analytics: true }. |
CookiePilot.showSettings() | Otevře modal s předvolbami. |
CookiePilot.hideSettings() | Zavře modal s předvolbami. |
CookiePilot.showMyConsent() / hideMyConsent() | Zobrazí/skryje plovoucí tlačítko. |
Příklad
const consent = CookiePilot.getConsent();
// { necessary: true, analytics: true, marketing: false, preferences: false }
CookiePilot.updateConsent({ analytics: true });
document.getElementById('cookie-settings').addEventListener('click', () => {
CookiePilot.showSettings();
});
Odkaz „Spravovat cookies“ v patičce
<a href="#" onclick="CookiePilot.showSettings(); return false;">Spravovat cookies</a>
JavaScriptové eventy
Widget dispatchuje nativní event cookiepilot:consent na window. Listener musí být zaregistrován dříve, než se widget načte, pokud chcete zachytit event pro vracejícího se uživatele (dispatch se odešle ihned po startu 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 obsahuje stejný payload jako getConsent(). Pro integraci přes GTM použijte místo tohoto dataLayer event popsaný výše, protože dataLayer je persistent array a GTM zpracuje i historické eventy.
Kategorie souhlasů
| Kategorie | Popis | Výchozí |
|---|---|---|
necessary | Nezbytné pro fungování webu | Vždy aktivní |
analytics | Statistiky a analytika | Vyžaduje souhlas |
marketing | Reklama a remarketing | Vyžaduje souhlas |
preferences | Personalizace, jazyk | Vyžaduje souhlas |
Mapování na Google Consent Mode
| Kategorie CookiePilot | Pole Consent Mode |
|---|---|
analytics | analytics_storage |
marketing | ad_storage, ad_user_data, ad_personalization |
preferences | functionality_storage, personalization_storage |
| (vždy) | security_storage: granted |
Google Consent Mode v2
Verze 2 přidala ad_user_data a ad_personalization (vyžadováno od března 2024 pro EU/EHP u reklam Google).
| Parametr | Popis |
|---|---|
ad_storage | Reklamní cookies |
analytics_storage | Analytické cookies |
ad_user_data | Odesílání dat uživatele do Google |
ad_personalization | Personalizace reklam |
functionality_storage | Funkční cookies |
personalization_storage | Personalizační cookies |
security_storage | Vždy granted |
Mechanismus:
- Stub nastaví všechna pole na
deniedsynchronně, swait_for_update: 500. - Po rozhodnutí uživatele widget odešle
gtag('consent', 'update', {...})s mapováním výše. - U vracejícího se uživatele se bod 2 odešle ihned po startu widgetu, na základě cookie.
Konfigurace vzhledu
V panelu: Doména → Konfigurace:
- Vzhled: pozice, barvy, rozložení (BAR / BOX / MODAL).
- Texty: nadpis, popis, popisky tlačítek, popisy kategorií. 13 jazyků (EN, PL, DE, FR, ES, IT, NL, PT, SV, CS, RO, EL, HU).
- Tlačítko souhlasů: plovoucí tlačítko „Nastavení cookies“ viditelné po prvním rozhodnutí (vlevo/vpravo dole).
- Custom CSS: pole pro vlastní styly. Widget se vykresluje v Shadow DOM, takže CSS selektory z hlavního dokumentu nebudou fungovat. Pouze přes toto pole.
Přístupnost (WCAG 2.1 AA)
- ✅ Ovládání klávesnicí (Tab, Shift+Tab, Enter, Escape).
- ✅ ARIA labels, role="dialog", aria-modal.
- ✅ Focus trap v modalu.
- ✅ Čtečka obrazovky (live regions při změně stavu).
- ✅ Responzivita.
Integrace
WordPress
Máme oficiální plugin: CookiePilot na WordPress.org.
- WordPress admin → Pluginy → Přidat nový → vyhledejte „CookiePilot“.
- Nainstalujte a aktivujte.
- Nastavení → CookiePilot → vložte API klíč z panelu.
Plugin sám vloží stub a tag do <head> (se správným pořadím před ostatními skripty) a poskytuje shortcode [cookiepilot_settings] pro odkaz „Spravovat cookies“ v patičce.
Pokud preferujete bez pluginu: použijte „Insert Headers and Footers“ a vložte snippet z kroku 2 Rychlého startu do sekce Header.
Shopify
- Obchod → Motivy → Upravit kód.
- V
theme.liquidvložte snippet před</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" zajistí, že se skript banneru spustí brzy. Pamatujte, že inline stub z Kroku 2a (výchozí souhlasy) přidáváte zvlášť, do <head> před tímto skriptem, např. přes next/script s dangerouslySetInnerHTML nebo přímo v app/layout.tsx.
FAQ
Zpomaluje skript web?
Bundle má cca 12 KB gzip a načítá se asynchronně. Bez vlivu na Core Web Vitals.
Jak dlouho se souhlasy uchovávají?
Cookie s rozhodnutím uživatele: výchozí 365 dní (konfigurovatelné v panelu). Události v analytice: 2 roky (TTL ClickHouse).
Odešle se event cookiepilot_consent_update pro vracejícího se uživatele?
Ano. Widget při startu načte cookie a pushne event do dataLayer. Trigger Custom Event v GTM se spustí při každé návštěvě, nejen při prvním rozhodnutí.
Kam nahlásit problém?
kontakt@cookiepilot.io nebo chat v panelu.
Testovací checklist po nasazení
Po instalaci CookiePilot ověřte konfiguraci před spuštěním reklamních kampaní.
1. Test před souhlasem uživatele
- Otevřete web v anonymním režimu a vymažte cookies pro doménu.
- Otevřete DevTools → Network a obnovte stránku.
- Před kliknutím na souhlas ověřte, že:
- nevznikají analytické/marketingové cookies, např.
_ga,_gcl_*,_fbp,_ttp, - marketingové tagy neodesílají requesty na Meta/TikTok/LinkedIn před marketingovým souhlasem,
- v
dataLayerje nastaven výchozí stavdeniedproad_storage,ad_user_data,ad_personalizationaanalytics_storage.
- nevznikají analytické/marketingové cookies, např.
2. Test po přijetí souhlasů
- Klikněte na „Přijmout vše“.
- V DevTools ověřte, zda se objevil event
cookiepilot_consent_update. - U tagů Google ověřte v GTM Preview / Tag Assistant, zda Consent Mode změnil stav na
grantedpro příslušné kategorie. - U GA4 ověřte v DebugView, zda eventy začaly přicházet po souhlasu.
- U Meta Pixel / TikTok / LinkedIn ověřte, zda se tagy spouštějí až po eventu
cookiepilot_consent_updatea podmínce marketingového souhlasu.
3. Test odmítnutí souhlasů
- Vymažte cookies a obnovte stránku.
- Klikněte na „Odmítnout vše“.
- Ověřte, že se marketingové cookies a requesty stále nespouštějí.
- Ověřte, že nezbytné funkce webu nadále fungují.
4. Nejčastější chyby
- Tag GA4/Google Ads se spouští na
Consent Initializationmísto pozdějšího triggeru. - Meta Pixel nebo TikTok Pixel nemá podmínku na
cookiepilot_consent.marketing. - Na webu zůstal starý, natvrdo zakódovaný tracker v
<head>před CookiePilot. - V dokumentaci nebo šabloně zůstala neaktuální URL skriptu nebo starý atribut identifikátoru místo aktuálního
cookiepilot.jssdata-cpkey.