---
title: Vite Favicon Not Showing or 404? Here's the Fix
description: A Vite favicon that 404s in production almost always has public/ in the href or was imported from src. How to reference icon files so they survive the build.
canonical: https://favicontools.com/fix/vite-favicon-not-showing
---

# Vite Favicon Not Showing or 404? Here's the Fix

Vite copies public/ to the output root and rewrites index.html at build time. A favicon that works in dev and 404s in production nearly always has the public/ segment in its path, or was imported from src and hashed.

## Two asset pipelines, one of which you want

Anything imported from src is part of the module graph: Vite inlines it or emits it with a content hash and rewrites the reference. That's right for UI images and wrong for a favicon, which has to answer at a fixed URL.

public/ is the escape hatch. Files there are never resolved, hashed, or inlined. They're copied to the root of the output with their names intact. So public/favicon.ico is served at /favicon.ico, and the href must be exactly that.

## The correct link tags

```html
<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" />
```

Root-absolute paths, no public/ segment. These live in index.html at the project root, not inside public/.

> **Never write public/ in the path:** Reference the file as /favicon.ico, not ./public/favicon.ico. The public segment doesn't exist in the built output, so that form works in some dev setups and then 404s in production. A relative path without the leading slash breaks differently, resolving against the current route.

## Vite favicon not showing: FAQ

### Why does my Vite favicon only 404 in the production build?

Because the path went through public/ or through an import, both of which change between dev and build. Open the built index.html and the output directory and confirm the href and the file agree.

### Do I need to import the favicon anywhere?

No. Files in public/ are deliberately outside the module graph. Import one and Vite emits a second hashed copy, leaving two files where you wanted one and nothing at /favicon.ico.

### The favicon 404s when I deploy under a sub-path.

Set base in vite.config.ts. Vite rewrites the asset URLs in index.html at build time, so open the built file afterwards and confirm the icon hrefs carry the prefix before shipping.
