Vite Public Folder Favicon: A Complete Setup Guide
You dropped favicon.svg into Vite's public folder, hit save, and the browser tab still shows a blank white square. The build works, the file is right there, yet the browser can't find it. This happens when developers treat Vite's public directory like any other static folder — and miss one critical rule about how Vite serves those files.
This is a focused walkthrough of the public/ folder. For the complete picture, including dark mode, Apple touch icons and common pitfalls, start with our Vite favicon guide.
The public folder is Vite's escape hatch for assets that need stable, unhashed URLs. Favicons are the textbook use case — and the most common source of confusion for Vite beginners.
Why Favicons Belong in Vite's Public Folder
Vite hashes imported assets in src/ for cache-busting (think assets/logo-a3f9c2.svg). Great for JS and CSS, terrible for favicons. Browsers cache favicons aggressively, and search engines need a predictable URL to show your icon in results.
Files in public/ skip the bundler entirely. Per Vite's official docs, anything in this directory is copied to the build output root and served at the root path. So public/favicon.svg becomes /favicon.svg — not /public/favicon.svg. Just the file name, prefixed with a slash.
Prerequisites
A working Vite project (run npm create vite@latest)
Favicon files ready as SVG, PNG, or ICO
Access to index.html in your project root
Step 1: Drop Favicon Files into public/
Place your icon files directly into the public/ directory at your project root. Most Vite scaffolds create this folder automatically.
Use simple, conventional filenames. Browsers find favicon.svg, favicon.ico, and apple-touch-icon.png at the root without extra config.
Step 2: Reference Files with Root-Relative Paths
Open index.html in your project root (not public/index.html — that file doesn't exist in Vite). Add link tags inside the <head> using absolute paths starting with /. This is the only place in a Vite project where you hard-code asset paths, because the public folder intentionally skips the import resolver.
The HTML spec defines rel='icon' as the standard way to declare favicons (WHATWG HTML Living Standard). Browsers pick the best match based on type and sizes attributes.
Step 3: Add a Dark Mode Variant
Modern browsers support a second SVG that activates automatically in dark themes. Add another link tag with a media query so users see the right icon when their system switches to dark mode.
You can also spin up npm run preview and open the Network tab in DevTools. You should see requests for favicon.svg, favicon.ico, and apple-touch-icon.png returning 200, not 404.
Common Pitfalls
Most Vite favicon bugs come from one of these mistakes. If your tab is blank or shows a generic icon, run through this list first.
Using /public/favicon.svg in your HTML. The public/ segment exists in source only. The browser requests /favicon.svg.
Importing the favicon in main.js. This produces a hashed URL and breaks browser caching. Let the HTML link tag handle it.
Putting files in src/assets/ instead. These get processed and renamed. Favicons need predictable paths for caching and SEO.
Forgetting the link tag entirely. Some browsers auto-request /favicon.ico, but Chrome and Firefox increasingly require explicit declarations for SVG support.
When the Public Folder Isn't Enough
The public folder is the right home for static, unchanging favicons. It gives you stable URLs that browsers cache reliably and search engines can index. If you later need dynamic favicons — notification badges, user avatars, live status indicators — you'll need JavaScript to swap the href attribute at runtime. Our guide on dynamic favicon JavaScript covers that pattern in detail.
Need help generating the right icon files first? Mzu favicondl produces SVG, PNG, ICO, and Apple Touch variants from a single source image. Drop them into public/, add your link tags, and your Vite app has a professional tab presence in minutes.
你把 favicon.svg 放进了 Vite 的 public 文件夹,保存后,浏览器标签页仍然显示一个空白方块。构建正常,文件就在那里,但浏览器就是找不到它。这种情况发生在开发者把 Vite 的 public 目录当作普通静态文件夹处理时——却忽略了 Vite 提供这些文件的一个关键规则。
public 文件夹是 Vite 为需要稳定、无哈希 URL 的资源准备的逃生舱。Favicon 是教科书式的用例——也是 Vite 初学者最常见的困惑来源。
favicon.svg를 Vite의 public 폴더에 넣고 저장했는데, 브라우저 에는 여전히 하 사각형만 표시됩니다. 빌드는 정상이고 파일도 그 자리에 있는데, 브라우저는 파일을 찾지 못합니다. 이는 개발자가 Vite의 public 디렉터리를 다른 정적 폴더처럼 다루면서, Vite가 이 파일들을 제공하는 방식에 대한 핵심 규칙을 놓칠 때 발생합니다.
public 폴더는 안정적이고 해시 처리되지 않은 URL이 필요한 자산을 위한 Vite의 우회 경로입니다. Favicon은 가장 전형적인 사용 사례이며, Vite 입문자들이 가장 자주 혼란을 겪는 지점이기도 합니다.
왜 favicon은 Vite의 public 폴더에 있어야 할까요
Vite는 src/에서 import한 자산에 캐시 무효화를 위해 해시를 부여합니다(예: assets/logo-a3f9c2.svg). JS와 CSS에는 적합하지만 favicon에는 좋지 않습니다. 브라우저는 favicon을 적극적으로 캐싱하며, 검색 엔진은 검색 결과에 아이콘을 표시하기 위해 예측 가능한 URL을 필요로 합니다.
public/ 폴더의 파일은 번들러를 완전히 우회합니다. Vite 공식 문서에 따르면, 이 디렉터리의 모든 파일은 빌드 출력 루트로 복사되어 루트 경로에서 제공됩니다. 따라서 public/favicon.svg는 /favicon.svg가 됩니다. /public/favicon.svg가 아닙니다. 파일 이름 앞에 슬래시만 붙인 형태입니다.
사전 준비
동작 중인 Vite 프로젝트(npm create vite@latest 실행)
SVG, PNG, ICO 형식으로 준비된 favicon 파일
프로젝트 루트의 index.html에 접근 가능한 상태
1단계: favicon 파일을 public/에 배치
아이콘 파일을 프로젝트 루트의 public/ 디렉터리에 직접 배치합니다. 대부분의 Vite 스캐폴드에서는 이 폴더가 자동으로 생성됩니다.
간단하고 관례적인 파일 이름을 사용합니다. 브라우저는 추가 설정 없이 루트 경로에서 favicon.svg, favicon.ico, apple-touch-icon.png를 찾습니다.
2단계: 루트 상대 경로로 파일 참조
프로젝트 루트의 index.html을 엽니다(public/index.html이 아닙니다 — Vite에는 해당 파일이 존재하지 않습니다). <head> 안에 /로 시작하는 절대 경로의 link 태그를 추가합니다. public 폴더는 의도적으로 import resolver를 우회하므로, Vite 프로젝트에서 자산 경로를 하드코딩하는 것은 이 경우가 유일합니다.
npm run preview를 실행한 뒤 DevTools의 Network 탭을 열어도 됩니다. favicon.svg, favicon.ico, apple-touch-icon.png 요청이 404가 아닌 200을 반환하는 것을 확인할 수 있습니다.
한 실수
대부분의 Vite favicon 버그는 다음 실수 중 하나에서 비롯됩니다. 이 비어 있거나 일반 아이콘만 표시된다면, 먼저 이 목록을 확인해 보시기 바랍니다.
HTML에 /public/favicon.svg를 사용하는 경우.public/ 세그먼트는 소스에만 존재합니다. 브라우저는 /favicon.svg를 요청합니다.
main.js에서 favicon을 import하는 경우. 이렇게 하면 URL이 해시 처리되어 브라우저 캐싱이 깨집니다. HTML link 태그로 처리하도록 합니다.
대신 src/assets/에 파일을 넣는 경우. 해당 파일들은 가공되고 이름이 변경됩니다. Favicon은 캐싱과 SEO를 위해 예측 가능한 경로가 필요합니다.
link 태그 자체를 누락하는 경우. 일부 브라우저는 /favicon.ico를 자동으로 요청하지만, Chrome과 Firefox는 SVG 지원을 위해 명시적 선언을 요구하는 비중이 점점 커지고 있습니다.
public 폴더만으로 부족한 경우
public 폴더는 정적이고 변하지 않는 favicon을 위한 적합한 위치입니다. 브라우저가 안정적으로 캐싱하고 검색 엔진이 색인할 수 있는 안정적인 URL을 제공합니다. 이후 알림 배지, 사용자 아바타, 실시간 상태 표시 같은 동적 favicon이 필요해지면, 런타임에 href 속성을 교체할 JavaScript가 필요합니다. dynamic favicon JavaScript 가이드에서 해당 패턴을 자세히 다룹니다.
먼저 적절한 아이콘 파일을 만드는 데 도움이 필요하신가요? Mzu favicondl은 단일 소스 이미지에서 SVG, PNG, ICO, Apple Touch 변형을 생성합니다. 생성된 파일을 public/에 넣고 link 태그를 추가하면, 몇 분 안에 Vite 앱에 전문적인 탭 아이콘이 갖춰집니다.
Dejaste tu favicon.svg en la carpeta public de Vite, pulsaste guardar y la pestaña del navegador sigue mostrando un cuadrado blanco en blanco. El build funciona, el archivo está ahí mismo y, aun así, el navegador no lo encuentra. Esto ocurre cuando se trata la carpeta public de Vite como cualquier otra carpeta estática y se pasa por alto una regla clave sobre cómo Vite sirve esos archivos.
La carpeta public es la vía de escape de Vite para los assets que necesitan URLs estables y sin hash. Los favicons son el caso de libro: la razón más habitual de confusión entre quienes empiezan con Vite.
Por qué los favicons van en la carpeta public de Vite
Vite aplica un hash a los assets importados desde src/ para invalidar caché (piensa en assets/logo-a3f9c2.svg). Genial para JS y CSS, pero pésimo para favicons. Los navegadores cachean los favicons de forma agresiva y los buscadores necesitan una URL predecible para mostrar tu icono en los resultados.
Los archivos en public/ se saltan el bundler por completo. Según la documentación oficial de Vite, todo lo que esté en este directorio se copia a la raíz del build y se sirve desde la raíz. Así, public/favicon.svg termina siendo /favicon.svg, no /public/favicon.svg. Solo el nombre del archivo, precedido por una barra.
Requisitos previos
Un proyecto Vite funcional (ejecuta npm create vite@latest)
Archivos de favicon listos en SVG, PNG o ICO
Acceso al index.html en la raíz del proyecto
Paso 1: coloca los archivos de favicon en public/
Coloca tus archivos de icono directamente en el directorio public/ en la raíz del proyecto. La mayoría de los scaffolds de Vite crean esta carpeta automáticamente.
Usa nombres de archivo simples y convencionales. Los navegadores encuentran favicon.svg, favicon.ico y apple-touch-icon.png en la raíz sin configuración extra.
Paso 2: referencia los archivos con rutas relativas a la raíz
Abre index.html en la raíz del proyecto (no public/index.html: ese archivo no existe en Vite). Añade etiquetas link dentro del <head> usando rutas absolutas que empiecen por /. Es el único punto del proyecto Vite donde se hardcodean rutas de assets, porque la carpeta public se salta a propósito el resolver de imports.
El estándar HTML define rel='icon' como la forma estándar de declarar favicons (WHATWG HTML Living Standard). Los navegadores eligen la mejor opción según los atributos type y sizes.
Paso 3: añade una variante para modo oscuro
Los navegadores modernos admiten un segundo SVG que se activa automáticamente en temas oscuros. Añade otra etiqueta link con una media query para que los usuarios vean el icono correcto cuando su sistema cambie a modo oscuro.
También puedes arrancar npm run preview y abrir la pestaña Network en DevTools. Deberías ver peticiones a favicon.svg, favicon.ico y apple-touch-icon.png devolviendo 200, no 404.
Errores habituales
La mayoría de problemas con favicons en Vite vienen de uno de estos errores. Si la pestaña aparece en blanco o muestra un icono genérico, repasa antes esta lista.
Usar /public/favicon.svg en tu HTML. El segmento public/ solo existe en el código fuente. El navegador pide /favicon.svg.
Importar el favicon en main.js. Esto genera una URL con hash y rompe la caché del navegador. Deja que la etiqueta link del HTML se encargue.
Poner los archivos en src/assets/. Acaban procesados y renombrados. Los favicons necesitan rutas predecibles para la caché y el SEO.
Olvidar la etiqueta link por completo. Algunos navegadores piden automáticamente /favicon.ico, pero Chrome y Firefox exigen cada vez más declaraciones explícitas para soportar SVG.
Cuando la carpeta public no basta
La carpeta public es el lugar adecuado para favicons estáticos que no cambian. Te ofrece URLs estables que los navegadores cachean de forma fiable y los buscadores pueden indexar. Si más adelante necesitas favicons dinámicos (badges de notificación, avatares de usuario, indicadores de estado en vivo), necesitarás JavaScript para cambiar el atributo href en tiempo de ejecución. Nuestra guía sobre favicon dinámico con JavaScript cubre ese patrón en detalle.
¿Necesitas ayuda para generar antes los archivos de icono correctos? Mzu favicondl produce variantes SVG, PNG, ICO y Apple Touch a partir de una única imagen de origen. Suéltalos en public/, añade tus etiquetas link y tu app Vite tendrá una presencia profesional en la pestaña en cuestión de minutos.
Generate Your Vite Favicon Files in Seconds
Drop your source image into Mzu favicondl, get SVG, PNG, ICO, and Apple Touch variants ready for your Vite public folder.