Contents
  1. The short answer
  2. Vite-based Vue projects
  3. Vue CLI projects
  4. Using an SVG logo as the favicon
  5. Why the old favicon still shows
  6. Changing the favicon at runtime
  7. Rights to the logo artwork
  8. What this guide does not cover

Vue does not manage the favicon itself. The icon is set by a link tag in the HTML page that loads your app. To change it, put your new icon file in the project's public folder and point that tag at it. Where the HTML file sits, and how the path is written, depends on whether the project uses Vite or the older Vue CLI.

The short answer

  • 1. Export your logo mark as a favicon file. SVG is a good primary format, with an ICO or PNG fallback.
  • 2. Place the file or files in the public folder at the project root.
  • 3. Edit the icon link tag in index.html so it references the new file name.
  • 4. Rebuild or restart the dev server, then hard-refresh. Browsers cache favicons aggressively.

Vite-based Vue projects

Projects scaffolded with the current official tooling use Vite. In these projects, index.html sits in the project root, not inside public. A default favicon file usually ships in public. Files in public are served from the site root unchanged, so you reference them with a root-relative path.

<head>
  <meta charset="UTF-8" />
  <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
  <link rel="icon" href="/favicon.ico" sizes="any" />
  <link rel="apple-touch-icon" href="/apple-touch-icon.png" />
  <title>My App</title>
</head>

If the app is deployed under a sub-path, set the base option in the Vite config. Vite rewrites root-relative asset paths in index.html to include that base at build time.

Vue CLI projects

Older projects built with Vue CLI keep the HTML template at public/index.html. The default icon tag uses a template variable for the base path. Keep that variable when you change the file name so deployments under a sub-path still resolve correctly.

<link rel="icon" href="<%= BASE_URL %>favicon.svg" type="image/svg+xml">
<link rel="icon" href="<%= BASE_URL %>favicon.ico" sizes="any">

Some Vue CLI setups include the PWA plugin. That plugin can inject its own icon tags and a manifest. If the old icon persists after you edit the template, check the plugin's icon settings and the manifest file too.

Using an SVG logo as the favicon

An SVG favicon scales cleanly to any size the browser requests. It can also respond to dark mode through a prefers-color-scheme media query inside the file. Browser support for SVG favicons is not universal, especially in older versions. Pairing the SVG with an ICO or PNG fallback is the safer default. No browser-version support data was supplied for this article, so test in the browsers your audience actually uses.

<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
  <style>
    path { fill: #1a1a1a; }
    @media (prefers-color-scheme: dark) {
      path { fill: #ffffff; }
    }
  </style>
  <path d="M4 4h24v24H4z" />
</svg>

The xmlns value in that snippet is the standard SVG namespace identifier. It is not a link. The square path is a placeholder for your own mark.

Before you rely on a logo SVG, open it in a vector editor or text editor and confirm it actually contains vector paths. The .svg extension alone does not guarantee that. Some SVG files only wrap an embedded raster image. Those files will not scale crisply, and they cannot have their colors edited the way true paths can.

Full logos rarely read well at favicon sizes. A simplified mark, monogram or symbol usually works better than a wordmark. Thin strokes and fine detail tend to disappear at small sizes, so simplify the artwork rather than just scaling it down.

Why the old favicon still shows

Browsers cache favicons separately from page content. They often keep showing the old icon after a correct change. Try these steps:

  • Do a hard refresh, or open the site in a private window.
  • Add a version query to the href, such as favicon.svg?v=2, to force a fresh request.
  • Check that the file name in the tag exactly matches the file in public, including case.
  • Remove any leftover default favicon.ico. Some browsers request that file at the site root even when no tag points to it.

Changing the favicon at runtime

Sometimes the icon needs to change while the app runs, for example to show a notification state or a per-route icon. You can update the existing link element from a component, a composable or a router hook. Because the tag lives outside the Vue app's mount point, you work with the document directly.

export function setFavicon(href) {
  let link = document.querySelector("link[rel~='icon']")
  if (!link) {
    link = document.createElement('link')
    link.rel = 'icon'
    document.head.appendChild(link)
  }
  link.href = href
}

If the project already uses a head-management library, set the icon through that library instead. Mixing the two approaches can leave competing tags in the head.

Rights to the logo artwork

Being able to download a logo file does not mean you may modify it or use it as a site icon. When you simplify a mark for favicon use, you are altering the artwork, and any fonts or trademarks in it carry their own terms. For a logo you do not own, confirm that the brand guidelines or license allow this use.

What this guide does not cover

No project-specific evidence was supplied, such as tool versions, browser support tables or measured file sizes. The steps above follow the documented default layouts of Vite and Vue CLI projects. Custom build setups, server-rendered frameworks built on Vue, and hosting platforms that inject their own headers may place the icon tag elsewhere. In those cases, check the framework's own configuration.