Vite でファビコンが表示されない・404 になる?その解決法
Vite は public/ を出力のルートにコピーし、ビルド時に index.html を書き換えます。開発では動作し本番で 404 になるファビコンは、ほぼ必ずパスに public/ のセグメントが含まれているか、src からインポートされてハッシュ化されています。
二つのアセットパイプライン、使うべきは一方だけ
src からインポートされたものはすべてモジュールグラフの一部です。Vite はそれをインライン化するか、コンテンツハッシュ付きで出力して参照を書き換えます。これは UI 画像には正しく、固定 URL で応答しなければならないファビコンには誤りです。
public/ が抜け道です。そこにあるファイルは解決も、ハッシュ化も、インライン化もされません。名前を保ったまま出力のルートにコピーされます。つまり public/favicon.ico は /favicon.ico で配信され、href はまさにその値でなければなりません。
正しい link タグ
<link rel="icon" href="/favicon.ico" sizes="any" />
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
<link rel="apple-touch-icon" href="/apple-touch-icon.png" />
<link rel="manifest" href="/site.webmanifest" />ルート絶対パスで、public/ のセグメントはありません。これらは public/ の中ではなく、プロジェクトルートの index.html に書きます。
Vite でファビコンが表示されない:よくある質問
Vite のファビコンが本番ビルドでだけ 404 になるのはなぜですか?
パスが public/ を経由したか、インポートを経由したためで、どちらも開発とビルドの間で変化します。ビルド後の index.html と出力ディレクトリを開いて、href とファイルが一致していることを確認してください。
ファビコンをどこかでインポートする必要はありますか?
いいえ。public/ のファイルは意図的にモジュールグラフの外にあります。インポートすると Vite が二つ目のハッシュ付きコピーを出力し、望んだ一つの代わりに二つのファイルが残り、/favicon.ico には何もなくなります。
サブパスにデプロイするとファビコンが 404 になります。
vite.config.ts で base を設定してください。Vite はビルド時に index.html のアセット URL を書き換えるので、あとでビルド後のファイルを開き、アイコンの href にプレフィックスが付いていることを確認してから出荷してください。