Nuxt Favicon Generator
Nuxt injects a link to /favicon.ico into every page by default, so a new project logs a 404 for it until you drop a file into public/. The remaining icons are declared in the app.head block of nuxt.config.
Config, not convention
Nuxt serves public/ from the site root, so public/favicon.ico is available at /favicon.ico with no configuration at all. The default head already links exactly that path, which is why the very first thing a fresh Nuxt project does is ask for an icon you have not created yet.
Everything past that one default is declarative. The app.head section of nuxt.config.ts holds a link array that is rendered into every page, which is the right place for icons because it applies before any route-level head calls run.
nuxt.config.ts
export default defineNuxtConfig({
app: {
head: {
link: [
{ rel: "icon", type: "image/x-icon", href: "/favicon.ico" },
{ rel: "icon", type: "image/png", sizes: "32x32", href: "/favicon-32x32.png" },
{ rel: "apple-touch-icon", href: "/apple-touch-icon.png" },
{ rel: "manifest", href: "/manifest.webmanifest" },
],
},
},
});Paths are root-absolute because they resolve against public/, which is served from the site root.
Where the files go
- my-nuxt-app/
- public/served from the site root
- favicon.icoadd
- favicon-32x32.pngadd
- apple-touch-icon.pngadd
- icon-192.pngadd
- icon-512.pngadd
- manifest.webmanifestadd
- assets/bundled and fingerprinted — not for icons
- app.vue
- nuxt.config.tswhere the tags are declared
Nuxt 3 vs Nuxt 2
Nuxt 3
Start hereCurrent
- Static files live in public/
- Head config nests under app.head in nuxt.config.ts
- useHead() is available in any component for overrides
- A default /favicon.ico link is present out of the box
Nuxt 2
End of life
- Static files live in static/, not public/
- Head config is a top-level head key in nuxt.config.js
- Components use the head() option instead of a composable
- Copying a Nuxt 3 config into it silently does nothing
Nuxt favicon FAQ
public/ or assets/?
public/ for anything that must stay at a known URL, which is every icon. assets/ goes through the bundler and comes out with a hashed name, so a request for /favicon.ico would never find it.
Can I change the favicon per route?
Yes — useHead() in a page can swap the icon, and browsers do follow the change during client-side navigation. The first paint still uses whatever app.head declared, so keep a sensible global default underneath it.
I upgraded from Nuxt 2 and the favicon disappeared.
Nuxt 2 served static/ and Nuxt 3 serves public/. Move the files across, and move the head configuration from the top-level head key into app.head at the same time, since the old key is ignored.