Dokumentation

CookiePilot-dokumentation

Den kompletta guiden till att installera, konfigurera och integrera CookiePilot på din webbplats.

Välj din installationsvägProva den interaktiva demon

Introduktion

CookiePilot är en plattform för samtyckeshantering (CMP), i linje med GDPR, lagen om elektronisk kommunikation (2022:482) och Google Consent Mode v2. I Sverige är det Integritetsskyddsmyndigheten (IMY) som utövar tillsyn över de här reglerna.

Vem den är för

  • Webbplatsägare: driftsätt utan att skriva en rad kod.
  • Utvecklare: API, händelser, GTM-integrationer.
  • Byråer: white-label, hantering av flera domäner.

Snabbstart

Steg 1: Registrera dig

  1. Skapa ett konto på app.cookiepilot.io/register.
  2. Lägg till din domän i panelen och kopiera API-nyckeln (formatet cp_live_...).

Steg 2: Installera koden

En direkt installation är två skript i <head>, i den här ordningen.

Steg 2a: Standardsamtycke (inline-stub). Klistra in det här först, före alla andra skript (cookiepilot.js, GA, GTM, annons- och spårningstaggar):

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

Det här inline-snippet sätter omedelbart varje kategori till denied (med wait_for_update: 500), så att standardläget för Google Consent Mode v2 är klart innan något annat laddas. För en återvändande besökare läser det det sparade samtycket direkt från cookien och avfyrar en consent update.

Steg 2b: Bannerskript. Lägg till det här direkt efter inline-stubben:

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

Steg 3: Konfigurera bannern

I panelen: Domän → Konfiguration → Utseende:

  • bannerns position (topp, botten, modal),
  • färger och texter,
  • en flytande knapp "Cookie-inställningar" för återvändande besökare.

Integration med Google Tag Manager

Genom GTM installerar du CookiePilot med en enda Custom HTML-tagg som sätter standardläget för samtycke och laddar bannern i GTM:s tidigaste fas. Du behöver ingen separat stub-fil eller en andra tagg.

I GTM, skapa en Custom HTML-tagg (Tags → New → Custom HTML) och klistra in:

<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. Taggen måste avfyras en gång per sida. Google-taggar (GA4, Google Ads), Facebook Pixel och andra marknadstaggar använder INTE triggern Consent Initialization; de avfyras senare (Consent Checks eller en samtyckesberoende trigger). Spara taggen och publicera GTM-containern.

Ordning och triggers

OrdningTaggTrigger
1CookiePilot - Consent Init + BannerConsent Initialization - All Pages
2GA4, Google Ads, UETAll Pages (Consent Mode sköter samtycket själv)
3Facebook Pixel, TikTok, LinkedIn m.fl.Custom Event cookiepilot_consent_update + samtyckesvillkor (se nedan)

Taggar utanför Google (Facebook Pixel, TikTok, LinkedIn)

Google Consent Mode täcker bara Google-taggar. För varje annat skript pushar widgeten en händelse till dataLayer vid varje samtyckesändring:

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

Händelsen avfyras också vid varje besök från en återvändande användare (när widgeten läser samtyckescookien), så GTM-triggern fungerar vid varje besök, inte bara vid det första beslutet.

Gemensamt mönster (gör det här en gång)

Du konfigurerar de här tre delarna en gång och återanvänder dem sedan för alla taggar utanför Google.

  1. Trigger (Triggers → New → Custom Event): Event name cookiepilot_consent_update. Inga villkor, inget "Once per page" (taggen måste kunna avfyras igen efter ett ändrat beslut).
  2. Data Layer Variable för varje kategori du använder:
    • Name cookiepilot_consent.marketing → variabel t.ex. dlv.cp_marketing
    • Name cookiepilot_consent.analytics → variabel t.ex. dlv.cp_analytics
    • Name cookiepilot_consent.preferences → variabel t.ex. dlv.cp_preferences
  3. Trigger Group eller ett villkor på triggern: dlv.cp_marketing equals true (för marknadstaggar) eller det relevanta fältet.

I vart och ett av exemplen nedan är Trigger samma Custom Event med ett villkor tillagt på rätt variabel.

Facebook Pixel

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

Valfritt, för full efterlevnad med Facebook Limited Data Use, lägg till en andra tagg som anropar fbq('consent','revoke') med triggern dlv.cp_marketing equals false.

TikTok Pixel

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

ttq.grantConsent() är TikToks nya API (infört 2024). Utan det tar TikTok emot hashade data utan samtycke, vilket bryter mot villkoren.

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

Hotjar hör under analytics, inte marketing (det mäter beteende, inte annonser). Kontrollera din egen cookiepolicy, en del företag klassificerar Hotjar annorlunda.

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

Microsoft Ads (UET)

UET har stött Google Consent Mode sedan slutet av 2023, så du behöver ingen Custom Event-trigger. Lägg till taggen på vanligt sätt (All Pages, Once per page) och UET läser ad_storage från GCM själv, det som widgeten sätter.

Kategorimappning (sammanfattning)

TaggKategoriFält i cookiepilot_consent
Facebook Pixelmarketingmarketing
TikTok Pixelmarketingmarketing
LinkedIn Insightmarketingmarketing
Pinterestmarketingmarketing
Hotjaranalyticsanalytics
Microsoft Clarityanalyticsanalytics
Mixpanel, Amplitudeanalyticsanalytics
Intercom, Drift, Crisppreferencespreferences
GA4, Google Ads, UET(GCM, ingen trigger)hanteras av gtag('consent','update')

API-referens

CookiePilot exponerar objektet window.CookiePilot:

MetodBeskrivning
CookiePilot.getConsent()Det aktuella samtyckesläget, eller null om inget beslut fattats.
CookiePilot.acceptAll()Samtyck till alla kategorier.
CookiePilot.rejectAll()Avvisar allt utom necessary.
CookiePilot.updateConsent(partial)Uppdaterar valda kategorier, t.ex. { analytics: true }.
CookiePilot.showSettings()Öppnar inställningsmodalen.
CookiePilot.hideSettings()Stänger inställningsmodalen.
CookiePilot.showMyConsent() / hideMyConsent()Visar/döljer den flytande knappen.

Exempel

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

CookiePilot.updateConsent({ analytics: true });

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

Länk "Hantera cookies" i sidfoten

<a href="#" onclick="CookiePilot.showSettings(); return false;">Hantera cookies</a>

JavaScript-händelser

Widgeten skickar en nativ cookiepilot:consent-händelse på window. Lyssnaren måste registreras innan widgeten laddas om du vill fånga händelsen för en återvändande besökare (utskicket sker omedelbart när widgeten startar):

<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 innehåller samma payload som getConsent(). För GTM-baserade integrationer, använd dataLayer-händelsen som beskrivs ovan i stället för den här, eftersom dataLayer är en persistent array och GTM plockar upp historiska händelser.


Samtyckeskategorier

KategoriBeskrivningStandard
necessaryKrävs för att webbplatsen ska fungeraAlltid på
analyticsStatistik och analysKräver samtycke
marketingAnnonsering och remarketingKräver samtycke
preferencesPersonalisering, språkKräver samtycke
CookiePilot-kategoriConsent Mode-fält
analyticsanalytics_storage
marketingad_storage, ad_user_data, ad_personalization
preferencesfunctionality_storage, personalization_storage
(alltid)security_storage: granted

Version 2 lade till ad_user_data och ad_personalization (obligatoriskt sedan mars 2024 i EU/EES för Google-annonsering).

ParameterBeskrivning
ad_storageAnnonscookies
analytics_storageAnalyscookies
ad_user_dataAtt skicka användardata till Google
ad_personalizationAnnonspersonalisering
functionality_storageFunktionella cookies
personalization_storagePersonaliseringscookies
security_storageAlltid granted

Så fungerar det:

  1. Stubben sätter varje fält till denied synkront, med wait_for_update: 500.
  2. Efter användarens beslut avfyrar widgeten gtag('consent', 'update', {...}) med mappningen ovan.
  3. För en återvändande besökare avfyras steg 2 omedelbart när widgeten startar, baserat på cookien.

Konfiguration av utseende

I panelen: Domän → Konfiguration:

  • Utseende: position, färger, layout (BAR / BOX / MODAL).
  • Texter: rubrik, beskrivning, knapptexter, kategoribeskrivningar. 13 språk (EN, PL, DE, FR, ES, IT, NL, PT, SV, CS, RO, EL, HU).
  • Samtyckesknapp: en flytande knapp "Cookie-inställningar" som visas efter det första beslutet (nere till vänster/höger).
  • Egen CSS: ett fält för dina egna stilar. Widgeten renderas i Shadow DOM, så CSS-selektorer från huvuddokumentet fungerar inte. Använd bara det här fältet.

Tillgänglighet (WCAG 2.1 AA)

  • ✅ Tangentbordsnavigering (Tab, Shift+Tab, Enter, Escape).
  • ✅ ARIA-etiketter, role="dialog", aria-modal.
  • ✅ Focus trap i modalen.
  • ✅ Stöd för skärmläsare (live regions vid tillståndsändring).
  • ✅ Responsiv design.

Integrationer

WordPress

Vi har ett officiellt plugin: CookiePilot på WordPress.org.

  1. WordPress-admin → Tillägg → Lägg till nytt → sök efter "CookiePilot".
  2. Installera och aktivera.
  3. Inställningar → CookiePilot → klistra in API-nyckeln från panelen.

Pluginet lägger själv in stubben och taggen i <head> (i rätt ordning, före andra skript) och tillhandahåller en shortcode [cookiepilot_settings] för en "Hantera cookies"-länk i sidfoten.

Om du föredrar att inte använda pluginet, använd "Insert Headers and Footers" och klistra in snippet från steg 2 i Snabbstarten i Header-sektionen.

Shopify

  1. Butik → Teman → Redigera kod.
  2. I theme.liquid, klistra in snippet före </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" säkerställer att bannerskriptet körs tidigt. Kom ihåg att inline-stubben från steg 2a (standardsamtycke) läggs till separat, i <head> före det här skriptet, till exempel via next/script med dangerouslySetInnerHTML eller direkt i app/layout.tsx.


Vanliga frågor

Saktar skriptet ner webbplatsen?

Bundeln är omkring 12 KB gzippad och laddas asynkront. Ingen påverkan på Core Web Vitals.

Hur länge lagras samtycket?

Användarens beslutscookie: 365 dagar som standard (konfigurerbart i panelen). Analyshändelser: 2 år (ClickHouse-TTL).

Ja. Widgeten läser cookien vid start och pushar händelsen till dataLayer. Custom Event-triggern i GTM avfyras vid varje besök, inte bara vid det första beslutet.

Var rapporterar jag ett problem?

kontakt@cookiepilot.io eller chatten i panelen.


Testchecklista efter driftsättning

När CookiePilot är installerat, verifiera konfigurationen innan du drar igång annonskampanjer.

1. Testa innan användaren ger samtycke

  1. Öppna webbplatsen i inkognitoläge och rensa cookies för domänen.
  2. Öppna DevTools → Network och ladda om sidan.
  3. Innan du klickar på samtycke, bekräfta att:
    • inga analys-/marknadscookies skapas, t.ex. _ga, _gcl_*, _fbp, _ttp,
    • marknadstaggar inte skickar requests till Meta/TikTok/LinkedIn före marknadssamtycke,
    • dataLayer har standardläget denied för ad_storage, ad_user_data, ad_personalization och analytics_storage.

2. Testa efter att samtycke accepterats

  1. Klicka på "Acceptera alla".
  2. Kontrollera i DevTools att händelsen cookiepilot_consent_update dök upp.
  3. För Google-taggar, kontrollera i GTM Preview / Tag Assistant att Consent Mode växlade läget till granted för de relevanta kategorierna.
  4. För GA4, kontrollera DebugView för att bekräfta att händelser börjar komma in efter samtycke.
  5. För Meta Pixel / TikTok / LinkedIn, kontrollera att taggarna bara avfyras efter händelsen cookiepilot_consent_update och marknadssamtyckesvillkoret.

3. Testa att avvisa samtycke

  1. Rensa cookies och ladda om sidan.
  2. Klicka på "Avvisa alla".
  3. Bekräfta att marknadscookies och requests fortfarande inte utlöses.
  4. Bekräfta att webbplatsens grundläggande funktioner fortfarande fungerar.

4. Vanliga misstag

  • GA4/Google Ads-taggen avfyras på Consent Initialization i stället för en senare trigger.
  • Meta Pixel eller TikTok Pixel saknar villkor på cookiepilot_consent.marketing.
  • En gammal, hårdkodad tracker ligger fortfarande i <head> före CookiePilot.
  • Dokumentationen eller mallen har fortfarande en föråldrad skript-URL eller ett gammalt identifierarattribut i stället för den aktuella cookiepilot.js med data-cpkey.

Samtyckesbevis, exporter och DSAR

CookiePilot registrerar samtyckeshändelser så att du kan rekonstruera sammanhanget kring ett besökarbeslut. En post kan innehålla händelsens tidpunkt, händelsetyp, domän, sid- eller käll-URL, samtyckesversion, kategorier och consent string när sådan finns, anonymiserad IP-adress, user-agent-hash, enhetstyp och webbläsare.

Exporter

  • Besökarens samtyckesbevis: JSON, CSV eller utskrivbar HTML.
  • Domänens revisionslogg: CSV eller JSON för ett valt datumintervall.
  • Exporterna är begränsade till din organisation och till de domäner du har åtkomst till.

DSAR-flöde

En Owner eller Admin kan starta en begäran om dataåtkomst från en samtyckesrad eller från DSAR-sidan i panelen. Panelen hittar besökarens händelser, visar intervallet och låter dig ladda ner bevisfiler. En raderingsbegäran kräver ett skäl och loggas i organisationens aktivitetsspår.

Begränsningar

Domänens revisionsexporter använder det valda datumintervallet och kan trunkeras för mycket stora resultatmängder. Lagringen av samtyckesloggen följer den aktiva planen och kontopolicyn, så den publika dokumentationen utlovar inte ett fast antal år.