JavaScript / Basico / 4 min
Banner de cookies GDPR minimal en JS
Script vanilla JS + CSS que muestra consentimiento GDPR/LGPD y bloquea GA y Meta Pixel hasta aceptar.
El GDPR y la LGPD exigen consentimiento explícito antes de cargar cookies de tracking. Este snippet bloquea Google Analytics y Meta Pixel hasta que el usuario acepta, guarda la preferencia en localStorage y no usa librerías externas.
Sirve como alternativa ligera a plugins de cookies que añaden demasiado JavaScript a páginas simples.
Guía de Implementación Paso a Paso
- Mueve Google Analytics y Meta Pixel fuera del
<head>. - Reemplaza
GA_MEASUREMENT_IDyMETA_PIXEL_ID. - Pega el snippet antes del cierre de
</body>. - Ajusta textos y enlaces a tu política de privacidad.
- Verifica en DevTools que
gtagyconnect.facebook.netno carguen antes del consentimiento.
HTML
<!-- KODFLUX - Cookie Consent Banner GDPR/LGPD -->
<!-- Pegar antes del </body>. Reemplaza GA_MEASUREMENT_ID y META_PIXEL_ID -->
<style>
#kf-cookie-banner {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: #1a1a2e;
color: #e2e8f0;
padding: 16px 24px;
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
z-index: 99999;
box-shadow: 0 -4px 20px rgba(0,0,0,0.3);
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
font-size: 14px;
flex-wrap: wrap;
}
#kf-cookie-banner p {
margin: 0;
flex: 1;
min-width: 200px;
line-height: 1.5;
}
#kf-cookie-banner a {
color: #63b3ed;
text-decoration: underline;
}
.kf-cookie-btns {
display: flex;
gap: 8px;
flex-shrink: 0;
}
.kf-btn-accept {
background: #4CAF50;
color: white;
border: none;
padding: 10px 20px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
font-weight: 600;
transition: background 0.2s;
}
.kf-btn-accept:hover {
background: #43a047;
}
.kf-btn-reject {
background: transparent;
color: #a0aec0;
border: 1px solid #4a5568;
padding: 10px 16px;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
transition: all 0.2s;
}
.kf-btn-reject:hover {
border-color: #718096;
color: #e2e8f0;
}
</style>
<div id="kf-cookie-banner" role="dialog" aria-label="Aviso de cookies" style="display:none;">
<p>
Usamos cookies propias y de terceros para analítica y marketing.
Puedes aceptar todas o solo las esenciales.
<a href="/politica-de-privacidad" target="_blank">Ver política de privacidad</a>.
</p>
<div class="kf-cookie-btns">
<button class="kf-btn-reject" onclick="kfCookieConsent(false)">Solo esenciales</button>
<button class="kf-btn-accept" onclick="kfCookieConsent(true)">Aceptar todas</button>
</div>
</div>
<script>
(function() {
'use strict';
const CONFIG = {
GA_ID: 'GA_MEASUREMENT_ID',
META_PIXEL_ID: 'META_PIXEL_ID',
COOKIE_VERSION: '1',
STORAGE_KEY: 'kf_cookie_consent',
EXPIRY_DAYS: 365,
};
function loadGoogleAnalytics() {
if (window.kfGALoaded) return;
window.kfGALoaded = true;
const script = document.createElement('script');
script.async = true;
script.src = `https://www.googletagmanager.com/gtag/js?id=${CONFIG.GA_ID}`;
document.head.appendChild(script);
window.dataLayer = window.dataLayer || [];
window.gtag = function() {
window.dataLayer.push(arguments);
};
gtag('js', new Date());
gtag('config', CONFIG.GA_ID, {
anonymize_ip: true,
cookie_flags: 'SameSite=None;Secure',
});
}
function loadMetaPixel() {
if (window.kfPixelLoaded || !CONFIG.META_PIXEL_ID || CONFIG.META_PIXEL_ID === 'META_PIXEL_ID') return;
window.kfPixelLoaded = true;
!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', CONFIG.META_PIXEL_ID);
fbq('track', 'PageView');
}
function saveConsent(accepted) {
try {
localStorage.setItem(CONFIG.STORAGE_KEY, JSON.stringify({
accepted,
version: CONFIG.COOKIE_VERSION,
date: new Date().toISOString(),
}));
} catch(e) {}
}
function getConsent() {
try {
const raw = localStorage.getItem(CONFIG.STORAGE_KEY);
if (!raw) return null;
const data = JSON.parse(raw);
if (data.version !== CONFIG.COOKIE_VERSION) return null;
return data;
} catch(e) {
return null;
}
}
window.kfCookieConsent = function(accepted) {
saveConsent(accepted);
document.getElementById('kf-cookie-banner').style.display = 'none';
if (accepted) {
loadGoogleAnalytics();
loadMetaPixel();
}
};
function init() {
const consent = getConsent();
if (consent === null) {
document.getElementById('kf-cookie-banner').style.display = 'flex';
} else if (consent.accepted) {
loadGoogleAnalytics();
loadMetaPixel();
}
}
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', init);
} else {
init();
}
})();
</script>
Prompt para Codex
TEXT
Crea un sistema completo de consentimiento de cookies GDPR/LGPD en HTML + CSS + JavaScript vanilla (sin dependencias externas).
Componentes requeridos:
HTML:
- Banner fijo en la parte inferior de la pantalla
- Texto explicativo con enlace a política de privacidad
- Dos botones: "Solo esenciales" y "Aceptar todas"
- role="dialog" y aria-label para accesibilidad
CSS:
- Fondo oscuro (#1a1a2e), texto claro
- Diseño responsive con flexbox y flex-wrap
- Botón "Aceptar" verde con hover, botón "Rechazar" con borde sutil
- Z-index alto (99999)
JavaScript:
- CONFIG con: GA_ID, META_PIXEL_ID, COOKIE_VERSION, STORAGE_KEY
- loadGoogleAnalytics(): inyecta script gtag dinámicamente con anonymize_ip
- loadMetaPixel(): inyecta el snippet estándar de Meta
- saveConsent(accepted): guarda en localStorage con fecha, versión y decisión
- getConsent(): lee y valida versión de localStorage
- window.kfCookieConsent(accepted): callback de los botones
- init(): si no hay consentimiento muestra banner; si aceptó carga scripts; si rechazó no carga nada
- Verificar versión de política y pedir consentimiento de nuevo si cambia
Texto en español, sin jQuery, compatible con navegadores modernos.