Checkbox de Consentimiento
Componente embebible que agrega un checkbox de consentimiento en formularios de contacto, descarga de recursos, registro, etc. Se renderiza con Shadow DOM para evitar conflictos de estilos. Registra el consentimiento en el backend de DPOLab con cadena de auditoria inmutable.
Instalacion rapida
<form id="contact-form">
<input type="text" id="nombre" name="nombre" required />
<input type="email" id="email" name="email" required />
<!-- Checkbox de consentimiento DPOLab -->
<div id="dpolab-consent"></div>
<button type="submit" id="submit-btn">Enviar</button>
</form>
<script src="https://api.dpolab.com/sdk/cmp-sdk.js"></script>
<script>
// Inicializar SDK (requerido una vez por pagina)
DPOLab.init({
widgetKey: 'WIDGET_KEY_DEL_BANNER_COOKIES',
apiUrl: 'https://api.dpolab.com',
});
// Renderizar checkbox de consentimiento
DPOLab.renderConsentCheckbox({
widgetKey: 'WIDGET_KEY_DE_LA_PLANTILLA',
purpose: 'privacy_policy',
label: 'He leido y acepto la',
linkText: 'Politica de Privacidad',
linkUrl: '/privacidad',
required: true,
submitButtonId: 'submit-btn',
emailFieldId: 'email',
}, 'dpolab-consent');
</script>El widgetKey del checkbox puede ser diferente al del init(). Esto permite tener un banner de cookies (init) y un checkbox de privacidad (renderConsentCheckbox) como plantillas separadas en DPOLab.
Configuracion completa
DPOLab.renderConsentCheckbox({
// ── Identificacion ──
widgetKey: 'abc-123-xyz', // Opcional — widgetKey de la plantilla. Si no se pasa, usa el de init()
purpose: 'privacy_policy', // Requerido — slug del proposito definido en la plantilla
// ── Texto del checkbox ──
label: 'He leido y acepto la', // Texto principal del checkbox
linkText: 'Politica de Privacidad', // Texto que se renderiza como hipervinculo despues del label
linkUrl: '/privacidad', // URL del hipervinculo. Si linkText esta vacio, no se muestra link
// ── Comportamiento ──
required: true, // Si es obligatorio aceptar para enviar el formulario
submitButtonId: 'submit-btn', // ID del boton submit — se deshabilita hasta que se acepte
emailFieldId: 'email', // ID del campo email — captura el email del titular (IDV nivel 1+)
// ── Verificacion de identidad (IDV) ──
idvLevel: 1, // Nivel de verificacion (ver tabla abajo). Si no se pasa, se lee de la plantilla
// ── Cuando grabar el consentimiento ──
recordOn: 'submit', // 'submit' (default) | 'change'. Ver seccion abajo.
// ── Apariencia ──
showBranding: true, // Muestra "Protegido por DPOLab" debajo del checkbox
// ── Callback ──
onChange: function(checked) { // Se ejecuta cada vez que el checkbox cambia de estado
console.log('Consent:', checked);
}
}, 'id-del-contenedor'); // ID del div donde se renderiza el checkboxParametros
| Parametro | Tipo | Requerido | Default | Descripcion |
|---|---|---|---|---|
widgetKey | string | No | del init() | Widget key de la plantilla. Permite usar una plantilla diferente al banner |
purpose | string | Si | — | Slug del proposito (ej: privacy_policy, comunicaciones) |
label | string | No | 'He leido y acepto la' | Texto principal del checkbox |
linkText | string | No | '' | Texto del hipervinculo. Si esta vacio, no se muestra link |
linkUrl | string | No | '#' | URL del hipervinculo |
required | boolean | No | false | Si se requiere aceptar para enviar. Se lee automaticamente de la plantilla si no se pasa |
submitButtonId | string | No | — | ID del boton submit a deshabilitar hasta aceptar |
emailFieldId | string | No | — | ID del campo email para capturar el email del titular |
idvLevel | number | No | de la plantilla | Nivel de verificacion de identidad (0-4) |
recordOn | 'change' | 'submit' | No | 'submit' | Cuando grabar el consentimiento en el backend. Ver seccion "Cuando se graba el consentimiento". |
showBranding | boolean | No | true | Muestra badge "Protegido por DPOLab" |
onChange | function | No | — | Callback (checked: boolean) => void |
Hipervinculo en el label
El linkText y linkUrl agregan un enlace clickeable al final del texto del label:
// Con link:
label: 'Acepto el tratamiento de mis datos conforme a la',
linkText: 'Politica de Privacidad',
linkUrl: '/privacidad',
// Renderiza: "Acepto el tratamiento de mis datos conforme a la [Politica de Privacidad]"
// Sin link:
label: 'Deseo recibir comunicaciones sobre ciberseguridad (opcional)',
// linkText no se pasa o se pasa vacio
// Renderiza: "Deseo recibir comunicaciones sobre ciberseguridad (opcional)"La URL del link depende del sitio donde se embebe el checkbox, no de la plantilla de DPOLab. Cada integrador configura la URL de su politica de privacidad.
Bloqueo del boton submit
Cuando required: true y se pasa submitButtonId, el SDK deshabilita automaticamente el boton de envio hasta que el checkbox se marque:
DPOLab.renderConsentCheckbox({
purpose: 'privacy_policy',
required: true,
submitButtonId: 'submit-btn', // El boton con este ID se deshabilita
}, 'dpolab-consent');Comportamiento:
- El boton se deshabilita al cargar (opacity 0.5, cursor not-allowed)
- Se habilita al marcar el checkbox
- Si hay multiples checkboxes requeridos apuntando al mismo boton, todos deben estar marcados
- Checkboxes con
required: falseno afectan al boton
El submitButtonId debe coincidir exactamente con el atributo id del boton HTML. El boton debe existir en el DOM antes de que el SDK se ejecute.
Niveles de verificacion de identidad (IDV)
El checkbox adapta su comportamiento segun el nivel de IDV configurado en la plantilla:
| Nivel | Nombre | Comportamiento del checkbox |
|---|---|---|
| 0 | Anonimo | Solo registra IP hash + session. No captura email |
| 1 | Email capturado | Lee el email del campo emailFieldId y lo registra junto al consentimiento |
| 2 | Email verificado | Al marcar, envia magic link al email. El consentimiento se registra tras verificacion |
| 3 | Identidad externa | Al marcar, abre popup del proveedor externo (ClaveUnica, SOYio). Registra tras verificacion |
| 4 | Identidad certificada | Al marcar, abre popup del proveedor de firma electronica. Registra tras verificacion |
// IDV nivel 1: captura email del formulario
DPOLab.renderConsentCheckbox({
purpose: 'privacy_policy',
required: true,
idvLevel: 1, // Captura email
emailFieldId: 'email', // Lee del campo con id="email"
submitButtonId: 'submit-btn',
}, 'dpolab-consent');Si no se pasa idvLevel, el SDK lo lee automaticamente de la plantilla de DPOLab. Se configura en CMP → Plantillas → Editar → Nivel de verificacion de identidad.
Multiples checkboxes
Puedes tener varios checkboxes en la misma pagina. Cada uno puede usar una plantilla diferente:
<!-- Privacidad (requerido) -->
<div id="dpolab-consent"></div>
<!-- Comunicaciones (opcional) -->
<div id="dpolab-marketing"></div>
<script>
DPOLab.init({
widgetKey: 'WIDGET_COOKIES',
apiUrl: 'https://api.dpolab.com',
});
// Checkbox 1: Politica de privacidad — requerido, bloquea submit
DPOLab.renderConsentCheckbox({
widgetKey: 'WIDGET_PRIVACIDAD',
purpose: 'privacy_policy',
label: 'Acepto el tratamiento de mis datos conforme a la',
linkText: 'Politica de Privacidad',
linkUrl: '/privacidad',
required: true,
submitButtonId: 'submit-btn',
emailFieldId: 'email',
}, 'dpolab-consent');
// Checkbox 2: Comunicaciones — opcional, sin link, sin branding duplicado
DPOLab.renderConsentCheckbox({
widgetKey: 'WIDGET_COMUNICACIONES',
purpose: 'comunicaciones',
label: 'Deseo recibir comunicaciones sobre ciberseguridad y proteccion de datos (opcional)',
required: false,
emailFieldId: 'email',
showBranding: false,
}, 'dpolab-marketing');
</script>Usa showBranding: false en el segundo checkbox para evitar duplicar el badge "Protegido por DPOLab".
Cuando se graba el consentimiento
A partir de mayo 2026 el SDK soporta dos modos. El default cambio para alinearse con la practica de la industria (OneTrust, Cookiebot, Usercentrics).
recordOn: 'submit' (recomendado, default)
El checkbox solo actualiza estado local al marcarse. El consentimiento se graba en el backend cuando el integrador llama DPOLab.recordConsent(purpose) en el submit del formulario.
document.getElementById('contact-form').addEventListener('submit', async function(e) {
e.preventDefault();
// 1. Validar que el checkbox este marcado (muestra error visual si no)
if (!DPOLab.validateConsent('privacy_policy')) return;
// 2. Grabar el consentimiento ANTES de enviar tu form al backend.
// Lee el email del campo configurado en `emailFieldId` (IDV nivel 1+).
// Retorna false si falta el email obligatorio, si el checkbox no esta
// marcado o si el endpoint del backend falla.
const recorded = await DPOLab.recordConsent('privacy_policy');
if (!recorded) return;
// 3. Enviar tu formulario normalmente
fetch('/api/contact', {
method: 'POST',
body: new FormData(document.getElementById('contact-form')),
});
});Este patron evita 3 escenarios de "consentimiento huerfano" que el modo 'change' no resuelve:
- Usuario marca el checkbox por curiosidad y cierra la pestana sin enviar el form → quedaba un record sin captacion de datos asociada.
- El submit del form falla por red o validacion del servidor → consentimiento grabado pero datos personales nunca procesados (discrepancia en auditoria).
- Bots y crawlers marcan checkboxes al explorar el sitio → records basura.
recordOn: 'change' (legacy)
El SDK graba al backend en el mismo momento en que el usuario marca el checkbox, sin esperar al submit del formulario.
DPOLab.renderConsentCheckbox({
purpose: 'privacy_policy',
recordOn: 'change', // Opt-in legacy
...
}, 'dpolab-consent');Solo conviene para:
- Checkbox de preferencias que no esta dentro de un
<form>(no hay submit que enganchar). - Migraciones desde versiones anteriores del SDK donde este era el comportamiento default.
Funciones publicas del SDK
| Funcion | Que hace | Cuando usarla |
|---|---|---|
DPOLab.isConsentGiven(purpose) | Devuelve true si el checkbox esta marcado. Sin efecto visual. | Para logica condicional (ej. mostrar campo opcional solo si acepta). |
DPOLab.validateConsent(purpose) | Devuelve true si esta marcado. Si no, pinta el borde rojo y muestra el mensaje de error. | En el submit, justo antes de recordConsent. |
DPOLab.recordConsent(purpose) | Graba el consentimiento en el backend (lee email del field, gestiona IDV). Async. Retorna true si se intento grabar, false si falta email obligatorio o el checkbox esta sin marcar. | En el submit, despues de validateConsent. |
Que se registra en el backend
Cuando se llama DPOLab.recordConsent() (modo 'submit') o al marcar el checkbox (modo 'change'), el SDK envia al backend:
- Proposito y decision (aceptado / rechazado)
- Origen:
CHECKBOX(se diferencia deBANNER,PREFERENCES,PRIVACY_CENTER,WEBHOOK,MANUAL) - Email del titular (si
emailFieldIdesta configurado y IDV nivel 1+) - IP hash (SHA-256, nunca la IP real — Art. 3 lit. c Ley 21.719)
- Cadena de auditoria (hash SHA-256 encadenado con el record anterior del aviso)
- Version del aviso que estaba vigente al momento de firmar
El consentimiento queda visible en el dashboard: CMP → Plantillas → Aviso → tab Detalle (registros + boton "Verificar cadena" para auditoria criptografica).
Apariencia
- Borde gris que cambia a teal al marcar
- Checkmark animado con transicion suave
- Estado de error: borde rojo + mensaje "Debes aceptar la politica de privacidad para continuar"
- Badge "Protegido por DPOLab" (ocultable con
showBranding: false) - Shadow DOM: estilos completamente aislados, sin conflictos con CSS del sitio
Compatibilidad
- Chrome 80+, Firefox 78+, Safari 14+, Edge 80+
- Shadow DOM para aislamiento de estilos
- Funciona dentro de cualquier framework (React, Vue, Angular, Astro, HTML puro)
Ver tambien
- Banner de Consentimiento — Banner de cookies con bloqueo de scripts
- Formulario ARCO — Widget de solicitudes de derechos
- Centro de Privacidad — Portal publico de gestion de datos