Favicon & App Icon ToolsVerificarCriar
Básico
Design

Favicons dinâmicos: exiba um badge ou status ao vivo

· 6 min read

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. 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. 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. 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. 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.

Keep reading