Favicons dinâmicos: exiba um badge ou status ao vivo
Aquele badge vermelho na aba do navegador é apenas um favicon sendo redesenhado. Veja como fazer isso sem uma etapa de build.
Por que não usar simplesmente um GIF?
Você pode definir um GIF animado como favicon, mas o suporte é irregular. O Firefox o anima. O Safari mostra apenas o primeiro quadro. O comportamento do Chrome mudou ao longo das versões. Isso serve para decoração, mas é a ferramenta errada para um badge ao vivo, porque você não consegue mudar o que o GIF mostra em tempo de execução.
Para uma contagem ou um status que se atualiza enquanto a aba está aberta, você precisa redesenhar a imagem em JavaScript. Um canvas oferece um buffer de pixels real no qual você pode pintar e depois entregar ao link do favicon como um data URI.
Como funciona
- 1
Carregue seu ícone base
Desenhe a imagem normal do seu favicon em um canvas pequeno, tipicamente 32x32. Esse é o ícone que os usuários veem quando não há nada para sinalizar.
- 2
Pinte o badge por cima
Quando houver uma contagem, desenhe um pequeno círculo preenchido em um canto e renderize o número dentro dele. Mantenha alto contraste para que ele seja legível a 32 pixels.
- 3
Troque o href do favicon
Defina o href do link do favicon como a saída do canvas. O navegador repinta a aba com sua nova imagem imediatamente.
- 4
Atualize a cada mudança
Execute de novo o desenhar-e-trocar sempre que a contagem mudar e redesenhe o ícone simples quando ela chegar a zero.
A troca, em 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 é uma Image que você carregou uma vez. Chame setFaviconBadge(unread) sempre que o número mudar. Limite a exibição a 9+ para que dois dígitos continuem legíveis.
Perguntas frequentes
Como mostro uma contagem de não lidos na aba do navegador?
Desenhe seu ícone e um badge com o número em um canvas e defina o href do link do favicon como canvas.toDataURL(). Execute de novo sempre que a contagem mudar. Não existe uma API separada de badge de aba para páginas web comuns.
Posso usar um GIF animado como favicon?
Pode, mas o suporte é inconsistente. O Firefox o anima, o Safari mostra o primeiro quadro e o Chrome variou. Para um badge ao vivo que se atualiza, use um canvas e troque o href.
Um favicon dinâmico prejudica o desempenho?
Não. Desenhar um canvas 32x32 e definir um data URI é barato. Basta redesenhar apenas quando o valor mudar, e não em um temporizador, e você não vai notar o custo.