Favicons dinámicos: muestra un badge o estado en vivo
Ese badge rojo en una pestaña del navegador es solo un favicon que se redibuja. Así se hace sin un paso de build.
¿Por qué no usar simplemente un GIF?
Puedes definir un GIF animado como favicon, pero el soporte es irregular. Firefox lo anima. Safari muestra solo el primer fotograma. El comportamiento de Chrome ha cambiado entre versiones. Eso sirve para decoración, pero es la herramienta equivocada para un badge en vivo, porque no puedes cambiar lo que muestra el GIF en tiempo de ejecución.
Para un contador o un estado que se actualiza mientras la pestaña está abierta, necesitas redibujar la imagen en JavaScript. Un canvas te da un búfer de píxeles real en el que puedes pintar y luego entregárselo al link del favicon como un data URI.
Cómo funciona
- 1
Carga tu ícono base
Dibuja la imagen normal de tu favicon en un canvas pequeño, típicamente de 32x32. Ese es el ícono que ven los usuarios cuando no hay nada que señalar.
- 2
Pinta el badge encima
Cuando haya un contador, dibuja un pequeño círculo relleno en una esquina y renderiza el número dentro. Mantén un alto contraste para que sea legible a 32 píxeles.
- 3
Cambia el href del favicon
Define el href del link del favicon como la salida del canvas. El navegador repinta la pestaña con tu nueva imagen de inmediato.
- 4
Actualiza en cada cambio
Vuelve a ejecutar el dibujar-y-cambiar cada vez que cambie el contador y redibuja el ícono simple cuando llegue a cero.
El cambio, en JavaScript puro
function setFaviconBadge(count) {
const canvas = document.createElement("canvas");
canvas.width = 32;
canvas.height = 32;
const ctx = canvas.getContext("2d");
// draw your base icon first (an <img> you preloaded)
ctx.drawImage(baseIcon, 0, 0, 32, 32);
if (count > 0) {
ctx.fillStyle = "#e5484d";
ctx.beginPath();
ctx.arc(23, 9, 9, 0, Math.PI * 2);
ctx.fill();
ctx.fillStyle = "#ffffff";
ctx.font = "bold 12px sans-serif";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText(count > 9 ? "9+" : String(count), 23, 10);
}
let link = document.querySelector("link[rel~='icon']");
if (!link) {
link = document.createElement("link");
link.rel = "icon";
document.head.appendChild(link);
}
link.href = canvas.toDataURL("image/png");
}baseIcon es una Image que cargaste una vez. Llama a setFaviconBadge(unread) cada vez que cambie el número. Limita la visualización a 9+ para que dos dígitos sigan siendo legibles.
Preguntas frecuentes
¿Cómo muestro un contador de no leídos en la pestaña del navegador?
Dibuja tu ícono y un badge con el número en un canvas y define el href del link del favicon como canvas.toDataURL(). Vuelve a ejecutarlo cada vez que cambie el contador. No existe una API de badge de pestaña aparte para páginas web normales.
¿Puedo usar un GIF animado como favicon?
Puedes, pero el soporte es inconsistente. Firefox lo anima, Safari muestra el primer fotograma y Chrome ha variado. Para un badge en vivo que se actualiza, usa un canvas y cambia el href.
¿Un favicon dinámico perjudica el rendimiento?
No. Dibujar un canvas de 32x32 y definir un data URI es barato. Basta con redibujar solo cuando cambie el valor, y no en un temporizador, y no notarás el costo.