Favicon не отображается или даёт 404 в Vite? Вот решение
Vite копирует public/ в корень вывода и переписывает index.html на этапе сборки. Favicon, который работает в dev и даёт 404 в продакшене, почти всегда имеет сегмент public/ в пути или был импортирован из src и получил хэш.
Два конвейера ассетов, из которых вам нужен один
Всё, что импортировано из src, входит в граф модулей: Vite встраивает это или выводит с хэшем содержимого и переписывает ссылку. Это правильно для картинок интерфейса и неправильно для favicon, который должен отвечать по фиксированному URL.
public/ — это запасной выход. Файлы там никогда не резолвятся, не хэшируются и не встраиваются. Они копируются в корень вывода с сохранением имён. Так что public/favicon.ico отдаётся по /favicon.ico, и href должен быть ровно таким.
Правильные теги link
<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" />Пути от корня, без сегмента public/. Они лежат в index.html в корне проекта, а не внутри public/.
Favicon не отображается в Vite: частые вопросы
Почему мой favicon в Vite даёт 404 только в продакшен-сборке?
Потому что путь прошёл через public/ или через импорт, а и то и другое меняется между dev и сборкой. Откройте собранный index.html и каталог вывода и убедитесь, что href и файл согласуются.
Нужно ли где-то импортировать favicon?
Нет. Файлы в public/ намеренно вне графа модулей. Импортируйте один — и Vite выведет вторую хэшированную копию, оставив два файла там, где вы хотели один, и ничего по /favicon.ico.
Favicon даёт 404 при деплое под подпутём.
Задайте base в vite.config.ts. Vite переписывает URL ассетов в index.html на этапе сборки, поэтому откройте собранный файл после этого и убедитесь, что href иконок несут префикс, прежде чем выкатывать.