Generate the set first (this tool does it in the browser, nothing uploaded), then follow the section for your stack. If you want to know why it's these five files, see the sizes & formats reference.
Plain HTML / static site
Drop the files next to your index.html (or in the folder your server treats as the web root) and paste four lines into the <head>:
<link rel="icon" href="/favicon.ico" sizes="any"> <link rel="icon" href="/icon.svg" type="image/svg+xml"> <link rel="apple-touch-icon" href="/apple-touch-icon.png"> <link rel="manifest" href="/site.webmanifest">
React with Vite
Vite serves everything in the public/ folder from the site root, untouched. Put the favicon files in public/, then add the same four <link> tags to index.html (the one in your project root, not inside src/). That's it — no import, no plugin.
React with Create React App
Same idea: the files go in public/. CRA already ships a public/index.html with a favicon.ico link and a manifest.json — replace those files and extend the head. Reference paths with %PUBLIC_URL% so they resolve under any deploy sub-path:
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" sizes="any"> <link rel="icon" href="%PUBLIC_URL%/icon.svg" type="image/svg+xml"> <link rel="apple-touch-icon" href="%PUBLIC_URL%/apple-touch-icon.png">
Next.js — App Router
This is the one framework that writes the tags for you. Next.js reads special filenames in the app/ directory and generates the correct <link> markup automatically. Just drop these in app/:
app/ favicon.ico → <link rel="icon"> icon.svg → <link rel="icon" type="image/svg+xml"> apple-icon.png → <link rel="apple-touch-icon"> (name it exactly this)
Note the Apple file must be named apple-icon.png (not apple-touch-icon.png) for the convention to fire. The Android/manifest icons still belong in a web manifest — put the PNGs in public/ and add a manifest.ts or link a static site.webmanifest. Don't also hand-write icon <link> tags in your layout, or you'll get duplicates.
Next.js — Pages Router
The file convention is App-Router-only. On the Pages Router, put the files in public/ and add the links in pages/_document.js inside <Head> (the next/document one, not next/head), so they render on every page:
<link rel="icon" href="/favicon.ico" sizes="any" /> <link rel="icon" href="/icon.svg" type="image/svg+xml" /> <link rel="apple-touch-icon" href="/apple-touch-icon.png" /> <link rel="manifest" href="/site.webmanifest" />
Vue, Astro & SvelteKit
All three follow the static-folder pattern:
- Vue (Vite): files in
public/, links in the rootindex.html. - Astro: files in
public/, links in your base layout's<head>. - SvelteKit: files in
static/, links insrc/app.htmlinside%sveltekit.head%'s surrounding<head>.
WordPress
Two honest options:
- The built-in way (easiest): Appearance → Customize → Site Identity → Site Icon, upload a square 512×512 PNG. WordPress generates the favicon and Apple touch icon tags for you. It won't emit an SVG icon or a true multi-size
.ico, but it covers the basics with zero code. - The precise way: add the four
<link>tags to your theme's<head>viafunctions.php, hookingwp_head, and upload the files to your theme or a top-level folder. Use this if you want the SVG dark-mode icon and a real ICO rather than what the Site Icon feature produces.
add_action('wp_head', function () {
echo '<link rel="icon" href="/favicon.ico" sizes="any">';
echo '<link rel="icon" href="/icon.svg" type="image/svg+xml">';
echo '<link rel="apple-touch-icon" href="/apple-touch-icon.png">';
});
The one rule that trips everyone up
Whatever the framework, the finished URLs must resolve at the domain root — https://yoursite.com/favicon.ico, not /assets/favicon.ico or /static/img/favicon.ico. Browsers and Google look for the icon at the root and at the exact paths in your <link> tags. That's why every framework above routes the files through its "served-from-root" folder (public/, static/, or app/). If your favicon "isn't showing," open yoursite.com/favicon.ico directly — a 404 there is the answer 90% of the time.
Next: which sizes you actually need · why Google shows the wrong favicon · back to the generator