9 frameworks · real paths, real markup

Favicon setup for your framework

Generating the files is the easy half. Installing them is where every framework goes its own way. Pick yours for the exact directory and the exact markup.

Drop an image
Drop a logo or image
PNG, JPG, WebP · square 512×512+ works best · non-square images are padded, never cropped · processed in your browser

Favicon Setup by Framework — Free, Fast & Private

Every framework on this page consumes the same seven files, because the browsers and platforms asking for them do not care what built your site. What differs, and differs more than people expect, is the two-step install: which directory the build treats as untouched static output, and how a tag gets into the head of a document you may never write by hand.

Those two answers range from "drop it in public/ and you are done" to "list the file in a JSON array or the build silently omits it". Guessing costs an afternoon. Each guide below shows the real path and the real snippet for one framework, along with the specific way that framework tends to fail.

Static directory and head mechanism, side by side

FrameworkStatic files go inHead is written in
Next.jsapp/ (file conventions) or public/app/layout.js — metadata export
Reactpublic/index.html (Vite) or public/index.html (CRA)
Vuepublic/index.html (create-vue) or public/index.html (Vue CLI)
Sveltestatic/src/app.html
Angularpublic/ (Angular 18+) or src/assets (earlier)src/index.html
Astropublic/src/layouts/Layout.astro (or a shared BaseHead.astro)
Nuxtpublic/ (project root, even in Nuxt 4)nuxt.config.ts — app.head.link
Ruby on Railsapp/assets/images/ or public/app/views/layouts/application.html.erb
Laravelpublic/resources/views/layouts/app.blade.php

Four patterns, nine frameworks

Read that table for a minute and the shape of the problem appears. There are really only four ways a framework handles this, and knowing which camp yours is in tells you most of what you need before you open a single guide.

The first camp is copy-verbatim plus a handwritten HTML file. Vite-based React, Vue and Astro all work this way, along with SvelteKit once you accept that its folder is called static/ rather than public/. Files go in, files come out unchanged, and you edit an HTML document that really exists in the repository. This is the easiest camp to work in and the easiest to break with a hardcoded absolute path when the site is later deployed under a subdirectory.

The second camp has no HTML file at all. Nuxt builds its document from a config object, so the head is an array of link descriptors in nuxt.config rather than markup. Next.js goes further and will generate the tags from filenames alone, appending a content hash that solves favicon cache-staleness for free. Both are more pleasant than they sound, and both punish you for mixing the declarative route with the manual one — duplicated icon tags are the standard symptom.

The third camp routes assets through a server-side pipeline. Rails fingerprints anything under app/assets and expects you to call a helper that resolves the digested URL, which is why favicon.ico still has to sit in public/ undigested for the bare root request browsers make regardless of your markup. Laravel skips the pipeline for these files entirely, because public/ is already the web server document root — the shortest path of any framework here, and the reason its classic failure is the zero-byte placeholder favicon nobody thinks to check.

The fourth camp is Angular on its own, and it is the only one where putting a file in a directory is not sufficient. The CLI copies exactly what the assets array in angular.json lists and ignores everything else, no matter how sensibly it is named. A favicon that works in development and 404s in production is nearly always that array.

What every guide assumes

All nine start from the same seven files, which is the complete set current platforms actually request: favicon.ico bundling the 16, 32 and 48 pixel entries; loose favicon-16x16.png and favicon-32x32.png for browsers that prefer PNG; favicon-48x48.png for desktop shortcuts; apple-touch-icon.png at 180 pixels for iOS home screens; and android-chrome-192x192.png plus android-chrome-512x512.png for the web app manifest. The longer lists you will find elsewhere are mostly fossils from platforms that no longer exist.

Two of those seven never appear in your HTML in any framework. The android-chrome pair is referenced from the manifest, which is what supplies the home screen icon and the splash image when someone installs your app. That distinction is invisible on a desktop browser and immediately obvious on an Android phone, so if installs matter to you, test on a real device rather than trusting the tab.

One habit is worth carrying into whichever guide you open: after the build, look at the output directory rather than the source tree, and request /favicon.ico directly in the address bar of the deployed site. Between them those two checks catch the file that never got copied, the path prefix nobody accounted for, and the single-page-app fallback rule that answers every unknown URL with HTML — three failures that look identical from the browser tab and have nothing in common underneath.

How it works

  1. Generate the set: Drop a square logo at 512px or larger into the tool above. The full set renders in your browser and nothing uploads.
  2. Find your framework below: Each guide names the exact static directory and the exact file where the head markup or config lives.
  3. Copy the files and the snippet: The snippets are complete and framework-specific — placeholders, helpers and config keys included, not a generic HTML block.
  4. Verify the build output: Check the built directory for all seven files, then request /favicon.ico on the deployed site to confirm it returns an image and not HTML.

Frequently asked questions

Why does favicon installation differ by framework at all?
Two reasons. Frameworks disagree about which directory is copied to the build output untouched — public/, static/, src/assets or app/assets — and they disagree about whether you write the head yourself, generate it from config, or let a file convention emit it. The files themselves are identical everywhere.
Which frameworks do not use a folder called public/?
SvelteKit uses static/. Rails uses app/assets/images for pipeline assets while keeping favicon.ico in public/. Angular uses public/ on newer versions and src/assets on older ones, but in either case the directory has to be listed in angular.json before anything is copied.
Do I need all seven files?
Five are load-bearing: favicon.ico, the 32px PNG, apple-touch-icon.png and the two android-chrome PNGs. The 16px and 48px PNGs are convenience copies of sizes already inside the .ico. Shipping all seven costs a few kilobytes and removes any guesswork.
Why is favicon.ico still required in 2026?
Browsers request /favicon.ico from the site root by convention when no link tag answers first, and that request is made against the literal path. A fingerprinted or hashed filename cannot satisfy it, which is why several frameworks in this list need an undigested copy at the root even when everything else goes through an asset pipeline.
My favicon works locally and not in production.
Three usual causes, in order: the file was never copied into the build output, the site is served under a path prefix that hardcoded absolute paths ignore, or a single-page-app fallback rewrites unknown URLs to index.html so the browser gets a document where it expected an image. Requesting the URL directly tells you which.
Does the generator upload my logo?
No. Every size is rendered with the Canvas API and the .ico container is assembled in JavaScript on your device. You can load this page, disconnect, and generate the full set offline — the simplest proof there is nothing to intercept.
My framework is not listed.
The files never change, so start from the closest match: anything built on Vite follows the React and Vue pattern, anything that generates HTML from config follows the Nuxt pattern, and anything with a server-side asset pipeline follows the Rails pattern. The plain generator page carries the framework-agnostic snippet.

All Image Tools

Solutions by use case