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 samtykkehaandtering (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 EOES-avtalen, og etterlevelsen foeres av Datatilsynet.

Hvem det er for

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

Hurtigstart

Steg 1: Registrer deg

  1. Opprett en konto paa app.cookiepilot.io/register.
  2. Legg til domenet ditt i panelet og kopier API-noekkelen (format cp_live_...).

Steg 2: Installer koden

En direkte installasjon er to skript i <head>, i denne rekkefoelgen.

Steg 2a: Standardsamtykke (inline stub). Lim inn dette foerst, foer 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 foer noe annet lastes. For en tilbakevendende besoekende 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 besoekende.

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

Rekkefoelge og triggere

RekkefoelgeTagTrigger
1CookiePilot - Consent Init + BannerConsent Initialization - All Pages
2GA4, Google Ads, UETAll Pages (Consent Mode haandterer 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 utloeses ogsaa ved hvert besoek fra en tilbakevendende bruker (naar widgeten leser samtykkecookien), saa GTM-triggeren virker ved hvert besoek, ikke bare ved den foerste beslutningen.

Felles moenster (gjoer 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 maa kunne utloeses paa 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 paa 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 paa 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 (innfoert i 2024). Uten det mottar TikTok hashede data uten samtykke, noe som bryter vilkaarene.

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 hoerer under analytics, ikke marketing (det maaler 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 stoettet Google Consent Mode siden slutten av 2023, saa du trenger ikke en Custom Event-trigger. Legg til taggen paa standard maate (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)haandtert av gtag('consent','update')

API-referanse

CookiePilot eksponerer objektet window.CookiePilot:

MetodeBeskrivelse
CookiePilot.getConsent()Naavaerende 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()Aapner 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 paa window. Lytteren maa registreres foer widgeten lastes hvis du vil fange hendelsen for en tilbakevendende besoekende (utsendelsen skjer umiddelbart naar 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
necessaryNoedvendig for at nettstedet skal virkeAlltid paa
analyticsStatistikk og analyseKrever samtykke
marketingAnnonsering og remarketingKrever samtykke
preferencesTilpasning, spraakKrever 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 (paakrevd siden mars 2024 i EOES 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 besoekende skjer steg 2 umiddelbart naar widgeten starter, basert paa cookien.

Utseendekonfigurasjon

I panelet: Domene → Konfigurasjon:

  • Utseende: plassering, farger, layout (BAR / BOX / MODAL).
  • Tekst: overskrift, beskrivelse, knappetekster, kategoribeskrivelser. 13 spraak (EN, PL, DE, FR, ES, IT, NL, PT, SV, CS, RO, EL, HU).
  • Samtykkeknapp: en flytende «Cookie-innstillinger»-knapp som vises etter den foerste beslutningen (nederst til venstre/hoeyre).
  • Custom CSS: et felt for dine egne stiler. Widgeten rendres i Shadow DOM, saa 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.
  • ✅ Stoette for skjermlesere (live regions ved tilstandsendring).
  • ✅ Responsivt design.

Integrasjoner

WordPress

Vi har en offisiell plugin: CookiePilot paa WordPress.org.

  1. WordPress-admin → Plugins → Add New → soek etter «CookiePilot».
  2. Installer og aktiver.
  3. Settings → CookiePilot → lim inn API-noekkelen fra panelet.

Pluginen setter selv inn stubben og taggen i <head> (i riktig rekkefoelge, 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 foer </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 kjoerer 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?

Bundelen er rundt 12 KB gzippet og lastes asynkront. Ingen paavirkning paa Core Web Vitals.

Hvor lenge lagres samtykket?

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

Ja. Widgeten leser cookien ved oppstart og pusher hendelsen til dataLayer. Custom Event-triggeren i GTM utloeses ved hvert besoek, ikke bare ved den foerste beslutningen.

Hvor melder jeg fra om et problem?

kontakt@cookiepilot.io eller chatten i panelet.


Testsjekkliste etter utrulling

Naar CookiePilot er installert, verifiser konfigurasjonen foer du starter annonsekampanjer.

1. Test foer brukeren gir samtykke

  1. Aapne nettstedet i inkognitomodus og toem cookies for domenet.
  2. Aapne DevTools → Network og last siden paa nytt.
  3. Foer du klikker paa samtykke, bekreft at:
    • ingen analyse-/markedscookies opprettes, f.eks. _ga, _gcl_*, _fbp, _ttp,
    • markedstagger ikke sender foresporsler til Meta/TikTok/LinkedIn foer 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 aa bekrefte at hendelser begynner aa komme inn etter samtykke.
  5. For Meta Pixel / TikTok / LinkedIn, sjekk at taggene bare utloeses etter cookiepilot_consent_update-hendelsen og betingelsen for markedssamtykke.

3. Test avvisning av samtykke

  1. Toem cookies og last siden paa nytt.
  2. Klikk «Avvis alle».
  3. Bekreft at markedscookies og foresporsler fremdeles ikke utloeses.
  4. Bekreft at noedvendige funksjoner paa nettstedet fremdeles virker.

4. Vanlige feil

  • GA4-/Google Ads-taggen utloeses paa Consent Initialization i stedet for en senere trigger.
  • Meta Pixel eller TikTok Pixel har ingen betingelse paa cookiepilot_consent.marketing.
  • En gammel, hardkodet sporer ligger fortsatt i <head> foer 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 besoekendes beslutning. En registrering kan inneholde tidspunktet for hendelsen, hendelsestype, domene, side- eller kilde-URL, samtykkeversjon, kategorier og consent string naar den er tilgjengelig, anonymisert IP-adresse, hash av user-agent, enhetstype og nettleser.

Eksporter

  • Samtykkebevis for en besoekende: 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 innsynsbegjaering fra en samtykkerad eller fra DSAR-siden i panelet. Panelet finner hendelsene til den besoekende, 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 svaert store resultatsett. Oppbevaringen av samtykkeloggen foelger den aktive planen og kontopolitikken, saa den offentlige dokumentasjonen lover ikke et fast antall aar.