Documentación

Documentación de CookiePilot

La guía completa para instalar, configurar e integrar CookiePilot en tu web.

Elige tu método de instalaciónPrueba la demo interactiva

Introducción

CookiePilot es una plataforma de gestión del consentimiento (CMP), conforme al RGPD, al artículo 22.2 de la LSSI (Ley 34/2002) y a Google Consent Mode v2.

Para quién es

  • Propietarios de webs: despliegue sin necesidad de programar.
  • Desarrolladores: API, eventos, integraciones con GTM.
  • Agencias: marca blanca, gestión multidominio.

Inicio rápido

Paso 1: Regístrate

  1. Crea una cuenta en app.cookiepilot.io/register.
  2. Añade tu dominio en el panel y copia la clave de API (formato cp_live_...).

Paso 2: Instala el código

Una instalación directa son dos scripts en el <head>, en este orden.

Paso 2a: Consentimiento por defecto (stub inline). Pega esto lo primero, antes que cualquier otro script (cookiepilot.js, GA, GTM, etiquetas de publicidad y seguimiento):

<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 pone de inmediato cada categoría en denied (con wait_for_update: 500), de modo que el estado por defecto de Google Consent Mode v2 queda listo antes de que se cargue nada más. Para un visitante recurrente lee el consentimiento guardado directamente de la cookie y dispara un consent update.

Paso 2b: Script del banner. Añádelo justo después del stub inline:

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

Paso 3: Configura el banner

En el panel: Dominio → Configuración → Apariencia:

  • posición del banner (arriba, abajo, modal),
  • colores y textos,
  • un botón flotante de «Configuración de cookies» para los visitantes recurrentes.

Integración con Google Tag Manager

Con GTM instalas CookiePilot con una sola etiqueta Custom HTML que fija el estado de consentimiento por defecto y carga el banner en la fase más temprana de GTM. No necesitas un archivo stub aparte ni una segunda etiqueta.

En GTM, crea una etiqueta Custom HTML (Etiquetas → Nueva → HTML personalizado) y pega:

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

Activador: Consent Initialization - All Pages. La etiqueta debe dispararse una vez por página. Las etiquetas de Google (GA4, Google Ads), Facebook Pixel y demás etiquetas de marketing NO usan el activador Consent Initialization; se disparan más tarde (Consent Checks o un activador dependiente del consentimiento). Guarda la etiqueta y publica el contenedor de GTM.

Orden y activadores

OrdenEtiquetaActivador
1CookiePilot - Consent Init + BannerConsent Initialization - All Pages
2GA4, Google Ads, UETAll Pages (Consent Mode gestiona el consentimiento por sí mismo)
3Facebook Pixel, TikTok, LinkedIn, etc.Custom Event cookiepilot_consent_update + condición de consentimiento (ver abajo)

Etiquetas ajenas a Google (Facebook Pixel, TikTok, LinkedIn)

Google Consent Mode solo cubre las etiquetas de Google. Para cualquier otro script, el widget envía un evento al dataLayer en cada cambio de consentimiento:

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

El evento también se dispara en cada visita de un usuario recurrente (cuando el widget lee la cookie de consentimiento), así que el activador de GTM funciona en cada visita, no solo en la primera decisión.

Patrón común (haz esto una vez)

Configuras estas tres piezas una sola vez y luego las reutilizas para todas las etiquetas ajenas a Google.

  1. Activador (Activadores → Nuevo → Evento personalizado): nombre del evento cookiepilot_consent_update. Sin condiciones, sin «Una vez por página» (la etiqueta debe poder dispararse de nuevo tras una decisión cambiada).
  2. Variable de capa de datos para cada categoría que uses:
    • Nombre cookiepilot_consent.marketing → variable, p. ej. dlv.cp_marketing
    • Nombre cookiepilot_consent.analytics → variable, p. ej. dlv.cp_analytics
    • Nombre cookiepilot_consent.preferences → variable, p. ej. dlv.cp_preferences
  3. Grupo de activadores o una condición en el activador: dlv.cp_marketing equals true (para etiquetas de marketing) o el campo que corresponda.

En cada uno de los ejemplos de abajo, el activador es el mismo Custom Event con una condición añadida sobre la variable adecuada.

Facebook Pixel

Etiqueta en GTM: Etiquetas → Nueva → HTML personalizado.

<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>
  • Activador: cookiepilot_consent_update + condición dlv.cp_marketing equals true.
  • Opciones de disparo de la etiqueta: Once per page.

Opcionalmente, para un pleno cumplimiento con Facebook Limited Data Use, añade una segunda etiqueta que llame a fbq('consent','revoke') con el activador dlv.cp_marketing equals false.

TikTok Pixel

Etiqueta en GTM: Etiquetas → Nueva → HTML personalizado.

<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>
  • Activador: cookiepilot_consent_update + condición dlv.cp_marketing equals true.
  • Opciones de disparo de la etiqueta: Once per page.

ttq.grantConsent() es la nueva API de TikTok (introducida en 2024). Sin ella, TikTok recibe datos con hash sin consentimiento, lo que incumple sus condiciones.

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>
  • Activador: cookiepilot_consent_update + condición dlv.cp_marketing equals true.
  • Opciones de disparo de la etiqueta: 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>
  • Activador: cookiepilot_consent_update + condición dlv.cp_analytics equals true.
  • Opciones de disparo de la etiqueta: Once per page.

Hotjar va bajo analytics, no marketing (mide el comportamiento, no la publicidad). Revisa tu propia política de cookies, algunas empresas clasifican Hotjar de otra 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>
  • Activador: cookiepilot_consent_update + condición dlv.cp_analytics equals true.
  • Opciones de disparo de la etiqueta: 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>
  • Activador: cookiepilot_consent_update + condición dlv.cp_marketing equals true.
  • Opciones de disparo de la etiqueta: Once per page.

Microsoft Ads (UET)

UET admite Google Consent Mode desde finales de 2023, así que no necesitas un activador Custom Event. Añade la etiqueta de la forma estándar (All Pages, Once per page) y UET lee ad_storage de GCM por sí mismo, que es lo que fija el widget.

Mapeo de categorías (resumen)

EtiquetaCategoríaCampo en cookiepilot_consent
Facebook Pixelmarketingmarketing
TikTok Pixelmarketingmarketing
LinkedIn Insightmarketingmarketing
Pinterestmarketingmarketing
Hotjaranalyticsanalytics
Microsoft Clarityanalyticsanalytics
Mixpanel, Amplitudeanalyticsanalytics
Intercom, Drift, Crisppreferencespreferences
GA4, Google Ads, UET(GCM, sin activador)gestionado por gtag('consent','update')

Referencia de la API

CookiePilot expone el objeto window.CookiePilot:

MétodoDescripción
CookiePilot.getConsent()El estado de consentimiento actual, o null si no se ha tomado ninguna decisión.
CookiePilot.acceptAll()Consentir todas las categorías.
CookiePilot.rejectAll()Rechaza todo salvo necessary.
CookiePilot.updateConsent(partial)Actualiza las categorías seleccionadas, p. ej. { analytics: true }.
CookiePilot.showSettings()Abre el modal de preferencias.
CookiePilot.hideSettings()Cierra el modal de preferencias.
CookiePilot.showMyConsent() / hideMyConsent()Muestra/oculta el botón flotante.

Ejemplo

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

CookiePilot.updateConsent({ analytics: true });

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

Enlace «Gestionar cookies» en el pie de página

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

Eventos JavaScript

El widget lanza un evento nativo cookiepilot:consent en window. El listener debe registrarse antes de que el widget se cargue si quieres captar el evento para un visitante recurrente (el disparo se produce de inmediato en cuanto arranca el widget):

<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 contiene la misma carga útil que getConsent(). Para integraciones basadas en GTM, usa el evento del dataLayer descrito arriba en lugar de este, porque el dataLayer es un array persistente y GTM recoge los eventos históricos.


Categorías de consentimiento

CategoríaDescripciónPor defecto
necessaryNecesarias para que la web funcioneSiempre activas
analyticsEstadísticas y analíticaRequiere consentimiento
marketingPublicidad y remarketingRequiere consentimiento
preferencesPersonalización, idiomaRequiere consentimiento
Categoría de CookiePilotCampos de Consent Mode
analyticsanalytics_storage
marketingad_storage, ad_user_data, ad_personalization
preferencesfunctionality_storage, personalization_storage
(siempre)security_storage: granted

La versión 2 añadió ad_user_data y ad_personalization (obligatorios desde marzo de 2024 en la UE/EEE para la publicidad de Google).

ParámetroDescripción
ad_storageCookies de publicidad
analytics_storageCookies de analítica
ad_user_dataEnvío de datos del usuario a Google
ad_personalizationPersonalización de anuncios
functionality_storageCookies funcionales
personalization_storageCookies de personalización
security_storageSiempre granted

Cómo funciona:

  1. El stub pone cada campo en denied de forma síncrona, con wait_for_update: 500.
  2. Tras la decisión del usuario, el widget dispara gtag('consent', 'update', {...}) usando el mapeo de arriba.
  3. Para un visitante recurrente, el paso 2 se dispara de inmediato en cuanto arranca el widget, en función de la cookie.

Configuración de la apariencia

En el panel: Dominio → Configuración:

  • Apariencia: posición, colores, disposición (BAR / BOX / MODAL).
  • Textos: título, descripción, etiquetas de los botones, descripciones de las categorías. 13 idiomas (EN, PL, DE, FR, ES, IT, NL, PT, SV, CS, RO, EL, HU).
  • Botón de consentimiento: un botón flotante de «Configuración de cookies» que se muestra tras la primera decisión (abajo a la izquierda/derecha).
  • CSS personalizado: un campo para tus propios estilos. El widget se renderiza en el Shadow DOM, así que los selectores CSS del documento principal no funcionarán. Usa únicamente este campo.

Accesibilidad (WCAG 2.1 AA)

  • ✅ Navegación por teclado (Tab, Shift+Tab, Enter, Escape).
  • ✅ Etiquetas ARIA, role="dialog", aria-modal.
  • ✅ Focus trap en el modal.
  • ✅ Compatibilidad con lectores de pantalla (live regions al cambiar de estado).
  • ✅ Diseño responsive.

Integraciones

WordPress

Tenemos un plugin oficial: CookiePilot en WordPress.org.

  1. Administración de WordPress → Plugins → Añadir nuevo → busca «CookiePilot».
  2. Instala y activa.
  3. Ajustes → CookiePilot → pega la clave de API del panel.

El plugin inserta el stub y la etiqueta en el <head> por sí mismo (en el orden correcto, por delante de otros scripts) y ofrece un shortcode [cookiepilot_settings] para un enlace «Gestionar cookies» en el pie de página.

Si prefieres no usar el plugin, usa «Insert Headers and Footers» y pega el snippet del Paso 2 del Inicio rápido en la sección Header.

Shopify

  1. Tienda → Temas → Editar código.
  2. En theme.liquid, pega el 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" garantiza que el script del banner se ejecute pronto. Recuerda que el stub inline del Paso 2a (consentimiento por defecto) se añade por separado, en el <head> por delante de este script, por ejemplo mediante next/script con dangerouslySetInnerHTML o directamente en app/layout.tsx.


Preguntas frecuentes

¿El script ralentiza la web?

El bundle ronda los 12 KB comprimido con gzip y se carga de forma asíncrona. Sin impacto en los Core Web Vitals.

¿Cuánto tiempo se conserva el consentimiento?

La cookie con la decisión del usuario: 365 días por defecto (configurable en el panel). Eventos de analítica: 2 años (TTL de ClickHouse).

Sí. El widget lee la cookie al arrancar y envía el evento al dataLayer. El activador Custom Event de GTM se dispara en cada visita, no solo en la primera decisión.

¿Dónde reporto un problema?

kontakt@cookiepilot.io o el chat del panel.


Lista de verificación tras el despliegue

Una vez instalado CookiePilot, verifica la configuración antes de lanzar campañas de publicidad.

1. Prueba antes de que el usuario dé su consentimiento

  1. Abre la web en modo incógnito y borra las cookies del dominio.
  2. Abre DevTools → Network y recarga la página.
  3. Antes de hacer clic en el consentimiento, confirma que:
    • no se crean cookies de analítica/marketing, p. ej. _ga, _gcl_*, _fbp, _ttp,
    • las etiquetas de marketing no envían peticiones a Meta/TikTok/LinkedIn antes del consentimiento de marketing,
    • el dataLayer tiene el estado por defecto denied para ad_storage, ad_user_data, ad_personalization y analytics_storage.

2. Prueba tras aceptar el consentimiento

  1. Haz clic en «Aceptar todo».
  2. En DevTools, comprueba que apareció el evento cookiepilot_consent_update.
  3. Para las etiquetas de Google, comprueba en GTM Preview / Tag Assistant que Consent Mode cambió el estado a granted para las categorías correspondientes.
  4. Para GA4, comprueba en DebugView que los eventos empiezan a llegar tras el consentimiento.
  5. Para Meta Pixel / TikTok / LinkedIn, comprueba que las etiquetas se disparan solo después del evento cookiepilot_consent_update y de la condición de consentimiento de marketing.

3. Prueba rechazando el consentimiento

  1. Borra las cookies y recarga la página.
  2. Haz clic en «Rechazar todo».
  3. Confirma que las cookies y peticiones de marketing siguen sin activarse.
  4. Confirma que las funciones esenciales de la web siguen funcionando.

4. Errores frecuentes

  • La etiqueta de GA4/Google Ads se dispara en Consent Initialization en lugar de en un activador posterior.
  • El Meta Pixel o el TikTok Pixel no tiene condición sobre cookiepilot_consent.marketing.
  • Un rastreador antiguo, escrito a fuego en el código, sigue en el <head> antes de CookiePilot.
  • La documentación o la plantilla todavía tiene una URL de script desactualizada o un atributo identificador antiguo en lugar del cookiepilot.js actual con data-cpkey.

Evidencia de consentimiento, exportaciones y DSAR

CookiePilot registra los eventos de consentimiento para que puedas reconstruir el contexto de la decisión de un visitante. Un registro puede incluir la hora del evento, el tipo de evento, el dominio, la URL de la página o de origen, la versión del consentimiento, las categorías y la consent string cuando está disponible, la dirección IP anonimizada, el hash del user-agent, el tipo de dispositivo y el navegador.

Exportaciones

  • Prueba de consentimiento de un visitante: JSON, CSV o HTML imprimible.
  • Registro de auditoría del dominio: CSV o JSON para un rango de fechas seleccionado.
  • Las exportaciones se limitan a tu organización y a los dominios a los que tienes acceso.

Flujo de DSAR

Un Owner o Admin puede iniciar una solicitud de acceso a datos desde una fila de consentimiento o desde la página de DSAR del panel. El panel encuentra los eventos del visitante, muestra el rango y permite descargar los archivos de prueba. Una solicitud de supresión requiere un motivo y queda registrada en el rastro de actividad de la organización.

Límites

Las exportaciones de auditoría de dominio usan el rango de fechas seleccionado y pueden truncarse en conjuntos de resultados muy grandes. La conservación del registro de consentimiento sigue el plan activo y la política de la cuenta, por lo que la documentación pública no promete un número fijo de años.