在 React 应用中添加 favicon 取决于你的构建工具:Create React App (CRA) 和 Vite 对文件的处理方式不同。本指南覆盖两者,以及如何在运行时切换 favicon(对深色模式或白标应用很有用)。
Create React App(CRA)
CRA 将静态文件放在 public/ 文件夹中。
- 将
favicon.ico放入public/。 - 打开
public/index.html并检查<link>标签(CRA 默认已包含一个):
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/apple-touch-icon.png" />
<link rel="manifest" href="%PUBLIC_URL%/site.webmanifest" />%PUBLIC_URL% 变量确保无论应用部署到哪里(子目录或根目录),路径都能正常工作。
Vite + React
Vite 是新 React 应用的现代默认选择。favicon 放在 public/中,但 HTML 模板是项目根目录下的 index.html(不在 public/ 里)。
- 将 favicon 文件放入
public/。 - 编辑根目录的
index.html,在<head>中添加 link 标签:
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png" />Vite 偏好 SVG favicon——注意 type="image/svg+xml" 声明。将 favicon.svg 放入 public/ 并使用前导斜杠进行引用。
一次上传即可获得所需的每个文件(ICO、各尺寸 PNG、SVG、Apple touch icon、manifest),就在 Favicon.one。
在运行时切换 favicon
对于深色模式 favicon 或白标应用,你可以用一个小型 hook 动态修改 favicon:
import { useEffect } from 'react'
function useFavicon(href: string) {
useEffect(() => {
let link = document.querySelector("link[rel~='icon']") as HTMLLinkElement
if (!link) {
link = document.createElement('link')
link.rel = 'icon'
document.head.appendChild(link)
}
link.href = href
}, [href])
}
// Usage
function App() {
useFavicon('/favicon-dark.svg')
return <div>...</div>
}完整的深色模式配置(自动切换)请参阅我们的 Favicon 深色模式指南。
使用 react-helmet
如果你已经在使用 react-helmet 或 react-helmet-async 来管理 <head>,可以以声明式方式声明 favicon:
<Helmet>
<link rel="icon" href="/favicon.ico" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
</Helmet>Next.js 与 React(CRA/Vite)的区别
如果你使用的是 Next.js,方式则不同——Next.js 拥有可自动生成标签的基于文件的约定。请参阅我们专门的 Next.js favicon 指南。
React favicon 常见问题
- 强制刷新。Vite 的开发服务器缓存非常激进。如果图标没有更新,请停止并重启
npm run dev。 - 文件夹错误。CRA 和 Vite 都要求文件在
public/而不是src/。 - 缺少前导斜杠。使用
/favicon.ico而非favicon.ico,这样路径才会从根目录解析。 - 构建产物缺少文件。构建后检查
dist/(Vite)或build/(CRA),确认 favicon 已被复制。
仍有问题?请查看完整的 "Favicon 不显示"检查清单。