Favicon do Vite não aparece ou dá 404? Veja a correção
O Vite copia public/ para a raiz da saída e reescreve o index.html em tempo de build. Um favicon que funciona em dev e dá 404 em produção quase sempre tem o segmento public/ no caminho, ou foi importado de src e recebeu hash.
Dois pipelines de assets, e você quer um deles
Qualquer coisa importada de src faz parte do grafo de módulos: o Vite a inclui inline ou a emite com um hash de conteúdo e reescreve a referência. Isso é certo para imagens de UI e errado para um favicon, que precisa responder em uma URL fixa.
public/ é a saída de emergência. Arquivos ali nunca são resolvidos, hasheados ou incluídos inline. São copiados para a raiz da saída com os nomes intactos. Então public/favicon.ico é servido em /favicon.ico, e o href precisa ser exatamente isso.
As tags de link corretas
<link rel="icon" href="/favicon.ico" sizes="any" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="manifest" href="/site.webmanifest" />Caminhos absolutos a partir da raiz, sem o segmento public/. Estes ficam no index.html na raiz do projeto, não dentro de public/.
Favicon do Vite não aparece: perguntas frequentes
Por que meu favicon do Vite só dá 404 no build de produção?
Porque o caminho passou por public/ ou por um import, e ambos mudam entre dev e build. Abra o index.html gerado no build e o diretório de saída e confirme que o href e o arquivo batem.
Preciso importar o favicon em algum lugar?
Não. Arquivos em public/ estão deliberadamente fora do grafo de módulos. Importe um e o Vite emite uma segunda cópia com hash, deixando dois arquivos onde você queria um e nada em /favicon.ico.
O favicon dá 404 quando faço deploy em um sub-caminho.
Defina base no vite.config.ts. O Vite reescreve as URLs de assets no index.html em tempo de build, então abra o arquivo gerado depois e confirme que os hrefs do ícone carregam o prefixo antes de publicar.