Skip to content

Cookies ​

document.cookie es una de las APIs más incómodas del navegador: es una sola cadena de texto que hay que partir a mano. Este snippet da funciones claras para leer, crear y borrar cookies, y un aviso de cookies listo para tu sitio.

¿Cookies, localStorage o sessionStorage? ​

CookieslocalStoragesessionStorage
Se envían al servidorSí, en cada peticiónNoNo
Capacidad~4 KB~5 MB~5 MB
CaducidadLa que definasNuncaAl cerrar la pestaña
Accesible desde JSSí (salvo HttpOnly)SíSí
Úsalas paraPreferencias que el servidor necesita, consentimientoCarrito, tema, borradoresDatos temporales de un flujo

Sesiones y tokens

Las cookies de sesión o autenticación debe crearlas el servidor con HttpOnly, Secure y SameSite. Desde JavaScript nunca podrás (ni deberías) leerlas. Este snippet es para cookies de preferencias.

Helpers ​

js
/**
 * Crea o actualiza una cookie.
 * @param {string} nombre
 * @param {string|number|object} valor objetos se guardan como JSON
 * @param {{ dias?: number, ruta?: string, dominio?: string, sameSite?: 'Lax'|'Strict'|'None', segura?: boolean }} opciones
 */
export function setCookie(nombre, valor, { dias = 365, ruta = '/', dominio, sameSite = 'Lax', segura = location.protocol === 'https:' } = {}) {
  const texto = typeof valor === 'object' ? JSON.stringify(valor) : String(valor);
  let cookie = `${encodeURIComponent(nombre)}=${encodeURIComponent(texto)}`;
  if (dias !== null) {
    const expira = new Date(Date.now() + dias * 864e5);
    cookie += `; expires=${expira.toUTCString()}`;
  }
  cookie += `; path=${ruta}; SameSite=${sameSite}`;
  if (dominio) cookie += `; domain=${dominio}`;
  if (segura || sameSite === 'None') cookie += '; Secure';
  document.cookie = cookie;
}

/** Lee una cookie. Devuelve null si no existe. Si contiene JSON, lo convierte */
export function getCookie(nombre) {
  const buscado = encodeURIComponent(nombre) + '=';
  const par = document.cookie.split('; ').find((c) => c.startsWith(buscado));
  if (!par) return null;
  const valor = decodeURIComponent(par.slice(buscado.length));
  try { return JSON.parse(valor); } catch { return valor; }
}

/** Todas las cookies como objeto */
export function getCookies() {
  return Object.fromEntries(
    document.cookie.split('; ').filter(Boolean).map((c) => {
      const i = c.indexOf('=');
      return [decodeURIComponent(c.slice(0, i)), decodeURIComponent(c.slice(i + 1))];
    })
  );
}

/** Borra una cookie (la ruta y el dominio deben coincidir con los de creación) */
export function deleteCookie(nombre, { ruta = '/', dominio } = {}) {
  document.cookie = `${encodeURIComponent(nombre)}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=${ruta}`
    + (dominio ? `; domain=${dominio}` : '');
}

Uso ​

js
import { setCookie, getCookie, deleteCookie } from './cookies.js';

setCookie('idioma', 'es');                               // 1 año
setCookie('ciudad', 'Guadalajara', { dias: 30 });
setCookie('preferencias', { moneda: 'MXN', vista: 'lista' });
setCookie('promo-cerrada', '1', { dias: 7 });            // no volver a mostrar el banner en 7 días
setCookie('temporal', 'x', { dias: null });              // cookie de sesión (muere al cerrar el navegador)

getCookie('idioma');            // "es"
getCookie('preferencias');      // { moneda: "MXN", vista: "lista" }
getCookie('no-existe');         // null

deleteCookie('ciudad');

Aviso de cookies (consentimiento) ​

Si usas Google Analytics, Meta Pixel u otras herramientas de seguimiento, la mayoría de leyes de privacidad (GDPR en Europa, LFPDPPP en México) piden informar y, en muchos casos, pedir consentimiento antes de cargarlas.

html
<div id="aviso-cookies" class="aviso-cookies" hidden role="dialog" aria-live="polite" aria-label="Aviso de cookies">
  <p>Usamos cookies propias y de terceros para analizar el tráfico y mejorar tu experiencia.
     <a href="/privacidad.html">Más información</a></p>
  <div class="acciones">
    <button data-consentimiento="rechazar" class="secundario">Sólo necesarias</button>
    <button data-consentimiento="aceptar">Aceptar todas</button>
  </div>
</div>
css
.aviso-cookies {
  position: fixed; left: 16px; right: 16px; bottom: 16px; z-index: 1000;
  max-width: 560px; margin: auto; padding: 18px 20px;
  background: #0f172a; color: #e2e8f0; border-radius: 14px;
  box-shadow: 0 10px 40px rgb(0 0 0 / .3); font: 14px/1.5 system-ui, sans-serif;
}
.aviso-cookies a { color: #a5b4fc; }
.aviso-cookies .acciones { display: flex; gap: 8px; justify-content: flex-end; flex-wrap: wrap; margin-top: 10px; }
.aviso-cookies button { border: 0; border-radius: 8px; padding: 9px 16px; font-weight: 600; cursor: pointer; background: #6366f1; color: #fff; }
.aviso-cookies button.secundario { background: transparent; color: #e2e8f0; border: 1px solid #475569; }
js
import { getCookie, setCookie } from './cookies.js';

const aviso = document.getElementById('aviso-cookies');
const consentimiento = getCookie('consentimiento'); // "aceptar" | "rechazar" | null

function cargarAnalitica() {
  // Sólo se carga si el usuario aceptó
  const s = document.createElement('script');
  s.async = true;
  s.src = 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXX';
  document.head.appendChild(s);
  window.dataLayer = window.dataLayer || [];
  window.gtag = function () { dataLayer.push(arguments); };
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXX', { anonymize_ip: true });
}

if (consentimiento === 'aceptar') cargarAnalitica();
if (!consentimiento) aviso.hidden = false;

aviso.addEventListener('click', (e) => {
  const decision = e.target.dataset.consentimiento;
  if (!decision) return;
  setCookie('consentimiento', decision, { dias: 180 });
  aviso.hidden = true;
  if (decision === 'aceptar') cargarAnalitica();
});

// Enlace en el footer para cambiar de opinión: <a href="#" id="config-cookies">Configurar cookies</a>
document.getElementById('config-cookies')?.addEventListener('click', (e) => {
  e.preventDefault();
  aviso.hidden = false;
});

Error común

Intentar borrar una cookie sin indicar la misma path con la que se creó. Si se creó en /tienda, deleteCookie('x') (que usa /) no la borra. Usa deleteCookie('x', { ruta: '/tienda' }).

Limitaciones de Safari

Safari (ITP) limita a 7 días las cookies creadas con JavaScript. Para preferencias que deban durar más, guárdalas también en localStorage o créalas desde el servidor.

Academia Web — aprende, copia y construye.