Documentação

Documentação do CookiePilot

O guia completo para instalar, configurar e integrar o CookiePilot no seu site.

Escolha o seu caminho de instalaçãoExperimentar a demo interativa

Introdução

O CookiePilot é uma plataforma de gestão de consentimento (CMP), em conformidade com o RGPD, com a Lei n.º 41/2004 (que transpõe a diretiva ePrivacy) e com o Google Consent Mode v2. Em Portugal, o cumprimento destas regras é fiscalizado pela CNPD (Comissão Nacional de Proteção de Dados).

Para quem é

  • Donos de sites: instalação sem escrever código.
  • Programadores: API, eventos, integrações com o GTM.
  • Agências: white-label, gestão de vários domínios.

Início rápido

Passo 1: Registo

  1. Crie uma conta em app.cookiepilot.io/register.
  2. Adicione o seu domínio no painel e copie a chave da API (formato cp_live_...).

Passo 2: Instalar o código

A instalação direta são dois scripts no <head>, por esta ordem.

Passo 2a: Consentimento por omissão (stub inline). Cole este primeiro, antes de qualquer outro script (cookiepilot.js, GA, GTM, tags de publicidade e de rastreio):

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

Este snippet inline define imediatamente todas as categorias como denied (com wait_for_update: 500), para que o estado por omissão do Google Consent Mode v2 esteja pronto antes de tudo o resto carregar. Para um visitante que regressa, lê o consentimento guardado diretamente do cookie e dispara um consent update.

Passo 2b: Script do banner. Adicione este logo a seguir ao stub inline:

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

Passo 3: Configurar o banner

No painel: Domínio → Configuração → Aparência:

  • posição do banner (topo, fundo, modal),
  • cores e textos,
  • um botão flutuante "Definições de cookies" para visitantes que regressam.

Integração com o Google Tag Manager

Através do GTM instala o CookiePilot com uma única tag Custom HTML que define o estado de consentimento por omissão e carrega o banner na fase mais inicial do GTM. Não precisa de um ficheiro stub separado nem de uma segunda tag.

No GTM, crie uma tag Custom HTML (Tags → Nova → HTML personalizado) e cole:

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

Acionador: Consent Initialization - All Pages. A tag deve disparar uma vez por página. As tags Google (GA4, Google Ads), o Facebook Pixel e outras tags de marketing NÃO usam o acionador Consent Initialization; disparam mais tarde (Consent Checks ou um acionador dependente do consentimento). Guarde a tag e publique o contentor do GTM.

Ordem e acionadores

OrdemTagAcionador
1CookiePilot - Consent Init + BannerConsent Initialization - All Pages
2GA4, Google Ads, UETAll Pages (o Consent Mode trata do consentimento)
3Facebook Pixel, TikTok, LinkedIn, etc.Custom Event cookiepilot_consent_update + condição de consentimento (ver abaixo)

Tags não Google (Facebook Pixel, TikTok, LinkedIn)

O Google Consent Mode cobre apenas as tags Google. Para todos os outros scripts, o widget envia um evento para o dataLayer a cada alteração do consentimento:

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

O evento dispara também em cada visita de um utilizador que regressa (quando o widget lê o cookie de consentimento), pelo que o acionador do GTM funciona em todas as visitas, não só na primeira decisão.

Padrão partilhado (faça isto uma vez)

Configura estes três elementos uma vez e depois reutiliza-os para todas as tags não Google.

  1. Acionador (Triggers → New → Custom Event): Event name cookiepilot_consent_update. Sem condições, sem "Once per page" (a tag tem de poder disparar de novo após uma decisão alterada).
  2. Data Layer Variable para cada categoria que usa:
    • Name cookiepilot_consent.marketing → variável, p. ex. dlv.cp_marketing
    • Name cookiepilot_consent.analytics → variável, p. ex. dlv.cp_analytics
    • Name cookiepilot_consent.preferences → variável, p. ex. dlv.cp_preferences
  3. Trigger Group ou uma condição no acionador: dlv.cp_marketing equals true (para tags de marketing) ou o campo relevante.

Em cada um dos exemplos abaixo, o Trigger é o mesmo Custom Event com uma condição adicionada na variável certa.

Facebook Pixel

Tag no 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>
  • Acionador: cookiepilot_consent_update + condição dlv.cp_marketing equals true.
  • Opções de disparo da tag: Once per page.

Opcionalmente, para conformidade total com o Facebook Limited Data Use, adicione uma segunda tag que chame fbq('consent','revoke') com o acionador dlv.cp_marketing equals false.

TikTok Pixel

Tag no 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>
  • Acionador: cookiepilot_consent_update + condição dlv.cp_marketing equals true.
  • Opções de disparo da tag: Once per page.

ttq.grantConsent() é a nova API do TikTok (introduzida em 2024). Sem ela, o TikTok recebe dados com hash sem consentimento, o que viola os termos.

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>
  • Acionador: cookiepilot_consent_update + condição dlv.cp_marketing equals true.
  • Opções de disparo da tag: 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>
  • Acionador: cookiepilot_consent_update + condição dlv.cp_analytics equals true.
  • Opções de disparo da tag: Once per page.

O Hotjar entra em analytics, não em marketing (mede comportamento, não anúncios). Verifique a sua própria política de cookies, algumas empresas classificam o Hotjar de outra forma.

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>
  • Acionador: cookiepilot_consent_update + condição dlv.cp_analytics equals true.
  • Opções de disparo da tag: 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>
  • Acionador: cookiepilot_consent_update + condição dlv.cp_marketing equals true.
  • Opções de disparo da tag: Once per page.

Microsoft Ads (UET)

O UET suporta o Google Consent Mode desde o final de 2023, pelo que não precisa de um acionador Custom Event. Adicione a tag da forma padrão (All Pages, Once per page) e o UET lê o ad_storage do próprio GCM, que o widget define.

Mapeamento de categorias (resumo)

TagCategoriaCampo em cookiepilot_consent
Facebook Pixelmarketingmarketing
TikTok Pixelmarketingmarketing
LinkedIn Insightmarketingmarketing
Pinterestmarketingmarketing
Hotjaranalyticsanalytics
Microsoft Clarityanalyticsanalytics
Mixpanel, Amplitudeanalyticsanalytics
Intercom, Drift, Crisppreferencespreferences
GA4, Google Ads, UET(GCM, sem acionador)tratado por gtag('consent','update')

Referência da API

O CookiePilot expõe o objeto window.CookiePilot:

MétodoDescrição
CookiePilot.getConsent()O estado atual do consentimento, ou null se nenhuma decisão foi tomada.
CookiePilot.acceptAll()Consentir todas as categorias.
CookiePilot.rejectAll()Rejeita tudo exceto necessary.
CookiePilot.updateConsent(partial)Atualiza categorias selecionadas, p. ex. { analytics: true }.
CookiePilot.showSettings()Abre o modal de preferências.
CookiePilot.hideSettings()Fecha o modal de preferências.
CookiePilot.showMyConsent() / hideMyConsent()Mostra/oculta o botão flutuante.

Exemplo

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

CookiePilot.updateConsent({ analytics: true });

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

Ligação "Gerir cookies" no rodapé

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

Eventos JavaScript

O widget dispara um evento nativo cookiepilot:consent no window. O listener tem de ser registado antes de o widget carregar se quiser apanhar o evento para um visitante que regressa (o disparo ocorre de imediato assim que o widget arranca):

<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 contém o mesmo payload que getConsent(). Para integrações baseadas no GTM, use o evento do dataLayer descrito acima em vez deste, porque o dataLayer é um array persistente e o GTM apanha eventos históricos.


Categorias de consentimento

CategoriaDescriçãoPor omissão
necessaryNecessários para o site funcionarSempre ativo
analyticsEstatísticas e analíticaRequer consentimento
marketingPublicidade e remarketingRequer consentimento
preferencesPersonalização, idiomaRequer consentimento
Categoria CookiePilotCampos do Consent Mode
analyticsanalytics_storage
marketingad_storage, ad_user_data, ad_personalization
preferencesfunctionality_storage, personalization_storage
(sempre)security_storage: granted

A versão 2 acrescentou ad_user_data e ad_personalization (obrigatórios desde março de 2024 na UE/EEE para a publicidade do Google).

ParâmetroDescrição
ad_storageCookies de publicidade
analytics_storageCookies de analítica
ad_user_dataEnvio de dados do utilizador para o Google
ad_personalizationPersonalização de anúncios
functionality_storageCookies funcionais
personalization_storageCookies de personalização
security_storageSempre granted

Como funciona:

  1. O stub define todos os campos como denied de forma síncrona, com wait_for_update: 500.
  2. Após a decisão do utilizador, o widget dispara gtag('consent', 'update', {...}) usando o mapeamento acima.
  3. Para um visitante que regressa, o passo 2 dispara de imediato assim que o widget arranca, com base no cookie.

Configuração da aparência

No painel: Domínio → Configuração:

  • Aparência: posição, cores, disposição (BAR / BOX / MODAL).
  • Textos: cabeçalho, descrição, rótulos dos botões, descrições das categorias. 13 idiomas (EN, PL, DE, FR, ES, IT, NL, PT, SV, CS, RO, EL, HU).
  • Botão de consentimento: um botão flutuante "Definições de cookies" mostrado após a primeira decisão (canto inferior esquerdo/direito).
  • CSS personalizado: um campo para os seus próprios estilos. O widget renderiza no Shadow DOM, por isso os seletores CSS do documento principal não funcionam. Use apenas este campo.

Acessibilidade (WCAG 2.1 AA)

  • ✅ Navegação por teclado (Tab, Shift+Tab, Enter, Escape).
  • ✅ Etiquetas ARIA, role="dialog", aria-modal.
  • ✅ Focus trap no modal.
  • ✅ Suporte a leitores de ecrã (live regions na mudança de estado).
  • ✅ Design responsivo.

Integrações

WordPress

Temos um plugin oficial: CookiePilot no WordPress.org.

  1. Administração do WordPress → Plugins → Adicionar novo → procure "CookiePilot".
  2. Instale e ative.
  3. Definições → CookiePilot → cole a chave da API a partir do painel.

O plugin insere ele próprio o stub e a tag no <head> (na ordem correta, à frente dos outros scripts) e disponibiliza um shortcode [cookiepilot_settings] para uma ligação "Gerir cookies" no rodapé.

Se preferir não usar o plugin, use o "Insert Headers and Footers" e cole o snippet do Passo 2 do Início rápido na secção Header.

Shopify

  1. Loja → Temas → Editar código.
  2. Em theme.liquid, cole o snippet antes de </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" garante que o script do banner corre cedo. Lembre-se de que o stub inline do Passo 2a (consentimento por omissão) é adicionado à parte, no <head> à frente deste script, por exemplo através de next/script com dangerouslySetInnerHTML ou diretamente em app/layout.tsx.


FAQ

O script atrasa o site?

O bundle tem cerca de 12 KB comprimido em gzip e carrega de forma assíncrona. Sem impacto nos Core Web Vitals.

Durante quanto tempo é guardado o consentimento?

O cookie de decisão do utilizador: 365 dias por omissão (configurável no painel). Eventos de analítica: 2 anos (TTL do ClickHouse).

Sim. O widget lê o cookie no arranque e envia o evento para o dataLayer. O acionador Custom Event no GTM dispara em cada visita, não só na primeira decisão.

Onde reporto um problema?

kontakt@cookiepilot.io ou o chat no painel.


Lista de verificação de testes pós-instalação

Depois de instalar o CookiePilot, verifique a configuração antes de lançar campanhas publicitárias.

1. Teste antes de o utilizador dar consentimento

  1. Abra o site em modo de navegação anónima e limpe os cookies do domínio.
  2. Abra o DevTools → Network e recarregue a página.
  3. Antes de clicar em consentir, confirme que:
    • não são criados cookies de analítica/marketing, p. ex. _ga, _gcl_*, _fbp, _ttp,
    • as tags de marketing não enviam pedidos para o Meta/TikTok/LinkedIn antes do consentimento de marketing,
    • o dataLayer tem o estado por omissão denied para ad_storage, ad_user_data, ad_personalization e analytics_storage.

2. Teste depois de aceitar o consentimento

  1. Clique em "Aceitar tudo".
  2. No DevTools, verifique se o evento cookiepilot_consent_update apareceu.
  3. Para as tags Google, verifique no GTM Preview / Tag Assistant se o Consent Mode mudou o estado para granted nas categorias relevantes.
  4. Para o GA4, verifique no DebugView se os eventos começam a chegar após o consentimento.
  5. Para o Meta Pixel / TikTok / LinkedIn, verifique se as tags disparam apenas após o evento cookiepilot_consent_update e a condição de consentimento de marketing.

3. Teste a rejeição do consentimento

  1. Limpe os cookies e recarregue a página.
  2. Clique em "Rejeitar tudo".
  3. Confirme que os cookies e pedidos de marketing continuam a não ser acionados.
  4. Confirme que as funcionalidades essenciais do site continuam a funcionar.

4. Erros comuns

  • A tag do GA4/Google Ads dispara em Consent Initialization em vez de um acionador posterior.
  • O Meta Pixel ou o TikTok Pixel não têm condição em cookiepilot_consent.marketing.
  • Um rastreador antigo, codificado à mão, ainda está no <head> antes do CookiePilot.
  • A documentação ou o modelo ainda têm um URL de script desatualizado ou um antigo atributo de identificador em vez do atual cookiepilot.js com data-cpkey.

Evidência de consentimento, exportações e DSAR

O CookiePilot regista eventos de consentimento para que possa reconstruir o contexto de uma decisão do visitante. Um registo pode incluir a hora do evento, o tipo de evento, o domínio, o URL da página ou da origem, a versão do consentimento, as categorias e a consent string quando disponível, o endereço IP anonimizado, o hash do user-agent, o tipo de dispositivo e o navegador.

Exportações

  • Prova de consentimento por visitante: JSON, CSV ou HTML imprimível.
  • Registo de auditoria do domínio: CSV ou JSON para um intervalo de datas selecionado.
  • As exportações estão limitadas à sua organização e aos domínios a que tem acesso.

Fluxo de DSAR

Um Owner ou Admin pode iniciar um pedido de acesso a dados a partir de uma linha de consentimento ou da página DSAR no painel. O painel encontra os eventos do visitante, mostra o intervalo e permite descarregar ficheiros de prova. Um pedido de eliminação exige um motivo e fica registado no rasto de atividade da organização.

Limites

As exportações de auditoria do domínio usam o intervalo de datas selecionado e podem ser truncadas para conjuntos de resultados muito grandes. A retenção do registo de consentimentos segue o plano ativo e a política da conta, por isso a documentação pública não promete um número fixo de anos.