Dokumentasjon

CookiePilot-dokumentasjon

Den komplette guiden til å installere, konfigurere og integrere CookiePilot med nettstedet ditt.

Velg installasjonsveiPrøv den interaktive demoen

Introduksjon

CookiePilot er en plattform for samtykkehåndtering (CMP) som er i samsvar med GDPR (personvernforordningen), den norske ekomloven (lov om elektronisk kommunikasjon) og Google Consent Mode v2. GDPR gjelder i Norge gjennom EØS-avtalen, og etterlevelsen føres av Datatilsynet.

Hvem det er for

  • Nettstedseiere: ta det i bruk uten å skrive kode.
  • Utviklere: API, hendelser, GTM-integrasjoner.
  • Byråer: white-label, forvaltning av flere domener.

Hurtigstart

Steg 1: Registrer deg

  1. Opprett en konto på app.cookiepilot.io/register.
  2. Legg til domenet ditt i panelet og kopier API-nøkkelen (format cp_live_...).

Steg 2: Installer koden

En direkte installasjon er to skript i <head>, i denne rekkefølgen.

Steg 2a: Standardsamtykke (inline stub). Lim inn dette først, før alle andre skript (cookiepilot.js, GA, GTM, annonse- og sporingstagger):

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

Denne inline-snutten setter umiddelbart hver kategori til denied (med wait_for_update: 500), slik at standardtilstanden for Google Consent Mode v2 er klar før noe annet lastes. For en tilbakevendende besøkende leser den det lagrede samtykket rett fra cookien og sender en consent update.

Steg 2b: Bannerskript. Legg dette til rett etter inline-stubben:

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

Steg 3: Konfigurer banneren

I panelet: Domene → Konfigurasjon → Utseende:

  • bannerplassering (topp, bunn, modal),
  • farger og tekst,
  • en flytende «Cookie-innstillinger»-knapp for tilbakevendende besøkende.

Integrasjon med Google Tag Manager

Gjennom GTM installerer du CookiePilot med en enkelt Custom HTML-tag som setter standardsamtykket og laster banneren i den tidligste GTM-fasen. Du trenger ingen egen stub-fil eller en ekstra tag.

I GTM oppretter du en Custom HTML-tag (Tags → New → Custom HTML) og limer inn:

<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å utløses en gang per side. Google-tagger (GA4, Google Ads), Facebook Pixel og andre markedstagger bruker IKKE Consent Initialization-triggeren; de utløses senere (Consent Checks eller en samtykkeavhengig trigger). Lagre taggen og publiser GTM-containeren.

Rekkefølge og triggere

RekkefølgeTagTrigger
1CookiePilot - Consent Init + BannerConsent Initialization - All Pages
2GA4, Google Ads, UETAll Pages (Consent Mode håndterer samtykket selv)
3Facebook Pixel, TikTok, LinkedIn osv.Custom Event cookiepilot_consent_update + samtykkebetingelse (se nedenfor)

Tagger utenom Google (Facebook Pixel, TikTok, LinkedIn)

Google Consent Mode dekker bare Google-tagger. For alle andre skript pusher widgeten en hendelse til dataLayer ved hver samtykkeendring:

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

Hendelsen utløses også ved hvert besøk fra en tilbakevendende bruker (når widgeten leser samtykkecookien), så GTM-triggeren virker ved hvert besøk, ikke bare ved den første beslutningen.

Felles mønster (gjør dette en gang)

Du konfigurerer disse tre delene en gang, og gjenbruker dem for alle tagger utenom Google.

  1. Trigger (Triggers → New → Custom Event): Event name cookiepilot_consent_update. Ingen betingelser, ingen «Once per page» (taggen må kunne utløses på nytt etter en endret beslutning).
  2. Data Layer Variable for hver kategori du bruker:
    • Name cookiepilot_consent.marketing → variabel f.eks. dlv.cp_marketing
    • Name cookiepilot_consent.analytics → variabel f.eks. dlv.cp_analytics
    • Name cookiepilot_consent.preferences → variabel f.eks. dlv.cp_preferences
  3. Trigger Group eller en betingelse på triggeren: dlv.cp_marketing equals true (for markedstagger) eller det relevante feltet.

I hvert av eksemplene nedenfor er Trigger den samme Custom Event med en betingelse lagt til på riktig variabel.

Facebook Pixel

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

Valgfritt, for full etterlevelse av Facebook Limited Data Use, legg til en ekstra tag som kaller fbq('consent','revoke') med triggeren dlv.cp_marketing equals false.

TikTok Pixel

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

ttq.grantConsent() er TikToks nye API (innført i 2024). Uten det mottar TikTok hashede data uten samtykke, noe som bryter vilkårene.

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

Hotjar hører under analytics, ikke marketing (det måler atferd, ikke annonser). Sjekk din egen cookie-policy, noen selskaper klassifiserer Hotjar annerledes.

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

Microsoft Ads (UET)

UET har støttet Google Consent Mode siden slutten av 2023, så du trenger ikke en Custom Event-trigger. Legg til taggen på standard måte (All Pages, Once per page), og UET leser ad_storage fra GCM selv, som widgeten setter.

Kategorikartlegging (oppsummering)

TagKategoriFelt 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)håndtert av gtag('consent','update')

API-referanse

CookiePilot eksponerer objektet window.CookiePilot:

MetodeBeskrivelse
CookiePilot.getConsent()Nåværende samtykketilstand, eller null hvis ingen beslutning er tatt.
CookiePilot.acceptAll()Samtykk til alle kategorier.
CookiePilot.rejectAll()Avviser alt bortsett fra necessary.
CookiePilot.updateConsent(partial)Oppdaterer valgte kategorier, f.eks. { analytics: true }.
CookiePilot.showSettings()Åpner innstillingsmodalen.
CookiePilot.hideSettings()Lukker innstillingsmodalen.
CookiePilot.showMyConsent() / hideMyConsent()Viser/skjuler den flytende knappen.

Eksempel

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

CookiePilot.updateConsent({ analytics: true });

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

«Administrer cookies»-lenke i bunnteksten

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

JavaScript-hendelser

Widgeten sender en nativ cookiepilot:consent-hendelse på window. Lytteren må registreres før widgeten lastes hvis du vil fange hendelsen for en tilbakevendende besøkende (utsendelsen skjer umiddelbart når widgeten starter):

<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 inneholder samme payload som getConsent(). For GTM-baserte integrasjoner bruker du dataLayer-hendelsen beskrevet ovenfor i stedet for denne, fordi dataLayer er et vedvarende array og GTM plukker opp historiske hendelser.


Samtykkekategorier

KategoriBeskrivelseStandard
necessaryNødvendig for at nettstedet skal virkeAlltid på
analyticsStatistikk og analyseKrever samtykke
marketingAnnonsering og remarketingKrever samtykke
preferencesTilpasning, språkKrever samtykke
CookiePilot-kategoriConsent Mode-felt
analyticsanalytics_storage
marketingad_storage, ad_user_data, ad_personalization
preferencesfunctionality_storage, personalization_storage
(alltid)security_storage: granted

Versjon 2 la til ad_user_data og ad_personalization (påkrevd siden mars 2024 i EØS for Google-annonsering).

ParameterBeskrivelse
ad_storageAnnonsecookies
analytics_storageAnalysecookies
ad_user_dataSender brukerdata til Google
ad_personalizationAnnonsetilpasning
functionality_storageFunksjonelle cookies
personalization_storageTilpasningscookies
security_storageAlltid granted

Slik virker det:

  1. Stubben setter hvert felt til denied synkront, med wait_for_update: 500.
  2. Etter brukerens beslutning sender widgeten gtag('consent', 'update', {...}) ved hjelp av kartleggingen ovenfor.
  3. For en tilbakevendende besøkende skjer steg 2 umiddelbart når widgeten starter, basert på cookien.

Utseendekonfigurasjon

I panelet: Domene → Konfigurasjon:

  • Utseende: plassering, farger, layout (BAR / BOX / MODAL).
  • Tekst: overskrift, beskrivelse, knappetekster, kategoribeskrivelser. 13 språk (EN, PL, DE, FR, ES, IT, NL, PT, SV, CS, RO, EL, HU).
  • Samtykkeknapp: en flytende «Cookie-innstillinger»-knapp som vises etter den første beslutningen (nederst til venstre/høyre).
  • Custom CSS: et felt for dine egne stiler. Widgeten rendres i Shadow DOM, så CSS-selektorer fra hoveddokumentet virker ikke. Bruk kun dette feltet.

Tilgjengelighet (WCAG 2.1 AA)

  • ✅ Tastaturnavigasjon (Tab, Shift+Tab, Enter, Escape).
  • ✅ ARIA-labels, role="dialog", aria-modal.
  • ✅ Fokusfelle i modalen.
  • ✅ Støtte for skjermlesere (live regions ved tilstandsendring).
  • ✅ Responsivt design.

Integrasjoner

WordPress

Vi har en offisiell plugin: CookiePilot på WordPress.org.

  1. WordPress-admin → Plugins → Add New → søk etter «CookiePilot».
  2. Installer og aktiver.
  3. Settings → CookiePilot → lim inn API-nøkkelen fra panelet.

Pluginen setter selv inn stubben og taggen i <head> (i riktig rekkefølge, foran andre skript) og tilbyr en [cookiepilot_settings]-shortcode for en «Administrer cookies»-lenke i bunnteksten.

Foretrekker du å ikke bruke pluginen, bruk «Insert Headers and Footers» og lim inn snutten fra Steg 2 i Hurtigstart i Header-seksjonen.

Shopify

  1. Butikk → Themes → Edit code.
  2. I theme.liquid, lim inn snutten før </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" sikrer at bannerskriptet kjører tidlig. Husk at inline-stubben fra Steg 2a (standardsamtykke) legges til separat, i <head> foran dette skriptet, for eksempel via next/script med dangerouslySetInnerHTML eller direkte i app/layout.tsx.


FAQ

Bremser skriptet nettstedet?

Skriptet er lett og lastes asynkront, så det blokkerer ikke rendringen. Den reelle effekten på Core Web Vitals avhenger også av nettstedets oppsett og de andre skriptene.

Hvor lenge lagres samtykket?

Cookien med brukerens beslutning: 365 dager som standard (konfigurerbart i panelet). Analysehendelser: 2 år (ClickHouse TTL).

Ja. Widgeten leser cookien ved oppstart og pusher hendelsen til dataLayer. Custom Event-triggeren i GTM utløses ved hvert besøk, ikke bare ved den første beslutningen.

Hvor melder jeg fra om et problem?

kontakt@cookiepilot.io eller chatten i panelet.


Testsjekkliste etter utrulling

Når CookiePilot er installert, verifiser konfigurasjonen før du starter annonsekampanjer.

1. Test før brukeren gir samtykke

  1. Åpne nettstedet i inkognitomodus og tøm cookies for domenet.
  2. Åpne DevTools → Network og last siden på nytt.
  3. Før du klikker på samtykke, bekreft at:
    • ingen analyse-/markedscookies opprettes, f.eks. _ga, _gcl_*, _fbp, _ttp,
    • markedstagger ikke sender foresporsler til Meta/TikTok/LinkedIn før markedssamtykke,
    • dataLayer har standardtilstanden denied for ad_storage, ad_user_data, ad_personalization og analytics_storage.

2. Test etter aksept av samtykke

  1. Klikk «Godta alle».
  2. I DevTools, sjekk at hendelsen cookiepilot_consent_update dukket opp.
  3. For Google-tagger, sjekk i GTM Preview / Tag Assistant at Consent Mode byttet tilstanden til granted for de relevante kategoriene.
  4. For GA4, sjekk DebugView for å bekrefte at hendelser begynner å komme inn etter samtykke.
  5. For Meta Pixel / TikTok / LinkedIn, sjekk at taggene bare utløses etter cookiepilot_consent_update-hendelsen og betingelsen for markedssamtykke.

3. Test avvisning av samtykke

  1. Tøm cookies og last siden på nytt.
  2. Klikk «Avvis alle».
  3. Bekreft at markedscookies og foresporsler fremdeles ikke utløses.
  4. Bekreft at nødvendige funksjoner på nettstedet fremdeles virker.

4. Vanlige feil

  • GA4-/Google Ads-taggen utløses på Consent Initialization i stedet for en senere trigger.
  • Meta Pixel eller TikTok Pixel har ingen betingelse på cookiepilot_consent.marketing.
  • En gammel, hardkodet sporer ligger fortsatt i <head> før CookiePilot.
  • Dokumentasjonen eller malen har fortsatt en utdatert skript-URL eller et gammelt identifikatorattributt i stedet for den gjeldende cookiepilot.js med data-cpkey.

Samtykkebevis, eksporter og DSAR

CookiePilot registrerer samtykkehendelser slik at du kan rekonstruere konteksten for en besøkendes beslutning. En registrering kan inneholde tidspunktet for hendelsen, hendelsestype, domene, side- eller kilde-URL, samtykkeversjon, kategorier og consent string når den er tilgjengelig, anonymisert IP-adresse, hash av user-agent, enhetstype og nettleser.

Eksporter

  • Samtykkebevis for en besøkende: JSON, CSV eller utskrivbar HTML.
  • Revisjonslogg for domenet: CSV eller JSON for et valgt datointervall.
  • Eksporter er avgrenset til organisasjonen din og til domenene du har tilgang til.

DSAR-arbeidsflyt

En Owner eller Admin kan starte en innsynsbegjæring fra en samtykkerad eller fra DSAR-siden i panelet. Panelet finner hendelsene til den besøkende, viser intervallet og lar deg laste ned bevisfiler. En sletteforesporsel krever en begrunnelse og logges i organisasjonens aktivitetsspor.

Begrensninger

Revisjonseksporter for domenet bruker det valgte datointervallet og kan bli avkortet for svært store resultatsett. Oppbevaringen av samtykkeloggen følger den aktive planen og kontopolitikken, så den offentlige dokumentasjonen lover ikke et fast antall år.