Favicon ToolsVerifyBuild
Framework

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 here

Current

  • 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.

Related platforms