初めてのAstroサイトを公開したのに、ブラウザのタブがデフォルトのAstroロゴのままになっている...そんな経験はないでしょうか。修正のポイントは1か所、Astroのfavicon publicフォルダのセットアップにあります。

Next.jsやNuxtとは異なり、Astroはpublicフォルダの扱いが独特です。このフォルダ内のファイルはViteのビルドパイプラインをバイパスし、最終的な出力ディレクトリへそのままコピーされます。これはfaviconアセットにとってまさに望ましい挙動ですが、闇雲にファイルを追加する前にその仕組みを理解しておく必要があります。

Astro favicon publicフォルダの仕組み

Astroのプロジェクト構造ドキュメントによると、publicフォルダはビルド時に処理を必要としないファイルのための場所です。faviconアセットはこのカテゴリに該当します。Viteによるハッシュ化・変換・最適化は望ましくありません。ブラウザが確実に取得できるよう、予測可能なURLで配信する必要があるからです。

/publicに置いたファイルは、デプロイ後のサイトのルート直下から配信されます。public/にfavicon.svgを置けば、それはhttps://yoursite.com/favicon.svgで配信されます。importもバンドラーによる解決も発生しません。

前提条件

ステップ1: faviconファイルを生成する

publicフォルダを触る前に、まずアセットを準備します。多くのプロジェクトでは以下の4ファイルが必要です。

このパッケージ一式はMzu favicondlを使えばワンクリックで生成でき、手動でリサイズする手間なく必要なサイズが揃います。

ステップ2: publicフォルダにファイルを配置する

プロジェクトのルートを開き、public/ディレクトリを確認します。用意したfaviconファイルをそのままコピーしてください。フォルダ構成は以下のようになります。

your-astro-project/
├── public/
│   ├── favicon.svg
│   ├── favicon-32x32.png
│   ├── apple-touch-icon.png
│   └── favicon.ico
├── src/
└── astro.config.mjs

ファイル名は小文字とハイフンで統一してください。ブラウザ側は区別しませんが、デプロイ先のサーバーOSによっては大文字小文字の扱いによって配信されるファイルが変わる可能性があります。命名規則は一貫させましょう。

ステップ3: layoutにlinkタグを追加する

public/に置いたファイルは自動でHTMLに反映されません。<link>タグで参照する必要があります。メインのlayoutコンポーネント(多くはsrc/layouts/Layout.astro)を開き、<head>内に以下のブロックを追加してください。

<link rel='icon' href='/favicon.svg' type='image/svg+xml'>
<link rel='icon' href='/favicon-32x32.png' sizes='32x32' type='image/png'>
<link rel='apple-touch-icon' href='/apple-touch-icon.png' sizes='180x180'>
<link rel='shortcut icon' href='/favicon.ico'>

このパターンはrel='icon'に関するHTML仕様に沿ったものです。モダンブラウザはSVGを優先し、古いブラウザはPNGにフォールバックし、ICOがレガシー環境を拾います。

ステップ4: ダークモードに対応する(任意)

明るい配色のfaviconはダークなブラウザUIに対して埋もれてしまいがちです。色を反転させた2つ目のSVGを用意し、メディアクエリで切り替えましょう。

<link rel='icon' href='/favicon.svg' type='image/svg+xml'>
<link rel='icon' href='/favicon-dark.svg' type='image/svg+xml' media='(prefers-color-scheme: dark)'>

両方のSVGをpublic/に配置してください。media属性によって、ユーザーのシステムテーマに応じてブラウザがどちらを読み込むかを決めます。JavaScriptは不要です。

ステップ5: ビルド出力を確認する

デプロイ前に本番ビルドを実行し、出力を確認します。publicフォルダの中身はdist/にそのまま現れるはずです。

npm run build
ls dist/

favicon.svg、favicon-32x32.pngなどがdist/のルート直下にあるはずです。もし見つからない場合は、誤ってpublic/assets/のようなサブディレクトリに入れていないか確認してください。その場合、/assets/favicon.svgに配置されてしまい、ルートには来ません。

よくある落とし穴

faviconをsrc/assets/に置いている。ここのファイルはViteによって処理・ハッシュ化・バンドルされるため、予測可能なURLを保てません。faviconファイルは必ずpublic/を使いましょう。

ブラウザキャッシュをクリアしていない。デプロイ後は強制リロード(Ctrl+Shift+R)を行うか、シークレットウィンドウで確認してください。ブラウザはfaviconを数日間にわたって積極的にキャッシュします。ユーザー側のブラウザでも強制的に更新したい場合は、faviconのキャッシュバスティングのベストプラクティスを参照してください。

sizes属性の指定漏れ。これがないとブラウザは16x16と仮定するため、PNGが拡大表示されてぼやけることがあります。実際の寸法は必ず宣言しましょう。

拡張子が大文字になっている。Favicon.PNGはmacOSでは動きますが、大文字小文字を区別するLinuxサーバーでは壊れます。小文字に統一してください(favicon.png)。

まとめ

これでAstro favicon publicフォルダのセットアップは完了です。publicディレクトリはビルドツールと競合せず、安定して予測可能なURLを提供してくれます。これはまさにfaviconに必要な特性です。ファイルを配置し、linkタグを結び付けて出力を確認すれば、あらゆるブラウザでタブがプロフェッショナルな見た目になります。

静的サイトジェネレーター全般(Next.js、Gatsby、Hugo)におけるfavicon戦略の全体像は、静的サイトジェネレーター向けfaviconガイドを参照してください。また、デプロイ後にアイコンが表示されない場合は、想像以上にシンプルな原因であることが多いものです。