Find your setup

built withfiles go intags go in
Vitepublic/index.html
Next.js App Routerapp/, renamedgenerated by Next.js, see Next.js
React Router (framework mode)public/the links export in app/root.tsx
Create React Apppublic/public/index.html

Vite

Copy the files into public/ and put the snippet in the <head> of index.html. Full details, including why not to import icons from src/, are on the Vite page.

<link rel="icon" href="/favicon.ico" sizes="32x32">
<link rel="icon" href="/icon.svg" type="image/svg+xml">
<link rel="icon" href="/favicon-96x96.png" type="image/png" sizes="96x96">
<link rel="apple-touch-icon" href="/apple-touch-icon.png">
<link rel="manifest" href="/manifest.webmanifest">

React Router

In framework mode, the root route renders the document and exposes a links function. Copy the files into public/ and return them from there:

// app/root.tsx
export const links = () => [
  { rel: 'icon', href: '/favicon.ico', sizes: '32x32' },
  { rel: 'icon', href: '/icon.svg', type: 'image/svg+xml' },
  { rel: 'icon', href: '/favicon-96x96.png', type: 'image/png', sizes: '96x96' },
  { rel: 'apple-touch-icon', href: '/apple-touch-icon.png' },
  { rel: 'manifest', href: '/manifest.webmanifest' },
]

Create React App

Create React App is deprecated, but many projects still run on it. Copy the files into public/ and edit public/index.html, where paths use the %PUBLIC_URL% placeholder:

<link rel="icon" href="%PUBLIC_URL%/favicon.ico" sizes="32x32">
<link rel="icon" href="%PUBLIC_URL%/icon.svg" type="image/svg+xml">
<link rel="icon" href="%PUBLIC_URL%/favicon-96x96.png" type="image/png" sizes="96x96">
<link rel="apple-touch-icon" href="%PUBLIC_URL%/apple-touch-icon.png">
<link rel="manifest" href="%PUBLIC_URL%/manifest.webmanifest">

The CRA template ships its own manifest.json and logo192.png. Replace them with the generated manifest and icons, or update the existing manifest to point at the new files.

Changing the favicon at runtime

To show an unread count or progress in the tab from React state, use the dynamic favicon module: call favicon.badge(n) from an effect, and favicon.reset() in its cleanup.

Questions

Can I import the favicon in a React component?

No. Favicons belong in the HTML document head, served from fixed paths. Importing them through the bundler gives them hashed names.

How do I change the favicon per page in React?

Update the href of the icon <link> from an effect, or use the dynamic module for badges. Crawlers only see the static icon, so keep that one stable.

Which framework option should I pick in the editor?

Vite for Vite, React Router and most client-rendered apps. Next.js for Next. The files are the same; only the install notes change.