favicon の更新・キャッシュ問題の調査
Electron アプリの favicon 表示は Application Support 配下の Chromium cache を確認する
5か月前
Electron アプリで外部サイトや連携先の favicon 表示が更新されない場合、アプリの起動引数やプロセス情報から user-data-dir を特定し、その配下の Cache/Cache_Data を確認する。macOS の Claude Desktop では ~/Library/Application Support/Claude/Cache/Cache_Data に Google s2 favicons や gstatic faviconV2 のレスポンスが保存されることがある。rg -a -l 'domain|faviconV2|google.com/s2/favicons' <user-data-dir>/Cache/Cache_Data や strings <cache-file> で content-location、expires、cache-control を確認すると、アプリ側ローカルキャッシュなのか外部サービス側キャッシュなのかを切り分けられる。
Next.js App Router の app/favicon.ico は自動で favicon metadata を生成する
5か月前
Next.js App Router では app/favicon.ico などの特殊ファイルを置くと、HTML head に favicon 用の metadata/link が自動生成される。layout.tsx の metadata.icons でも favicon を明示すると link rel="icon" が重複することがある。favicon URL を1本に統制したい場合は、favicon 実体を public/favicon.ico などの通常静的ファイルとして配置し、metadata.icons から明示的に参照する構成にすると自動生成と競合しにくい。
Google s2 favicon は外部キャッシュと content-location を確認して切り分ける
5か月前
ブラウザや外部アプリで favicon が更新されない場合、サイト本体の /favicon.ico や manifest アイコンが最新でも、Google の https://www.google.com/s2/favicons?domain=... は t*.gstatic.com にリダイレクトされ、独自の Cache-Control でキャッシュされる。curl -sSL -D headers.txt -o icon.png 'https://www.google.com/s2/favicons?domain=example.com&sz=96' を実行し、レスポンスヘッダーの content-location と cache-control を確認すると、Google がどのアイコン URL を採用しているか、更新待ちなのかを切り分けられる。
faviconが更新されないときはバージョンクエリでURLを変える
5か月前
ブラウザはfaviconをURL単位で極端に強くキャッシュし、Cache-Controlヘッダーを無視することが多い。特に/favicon.icoはlinkタグと無関係にブラウザが直接取得し、貼り付きやすい。
そのため、アイコン差し替え時にキャッシュヘッダーを設定するだけでは、すでにキャッシュ済みの古いアイコンは消えないことがある。確実なのはアイコンURLにバージョンクエリ(例: ?v=2)を付けてURL自体を変えること。差し替えのたびに数値を上げる。
併用パターン:
- ヘッダー(
Cache-Control: public, max-age=0, must-revalidate)で今後の再検証を保証(再発防止) - バージョンクエリでURLを変え、今のキャッシュを即時無効化
CDN/リバースプロキシ経由時はそちらのキャッシュパージも別途必要。
faviconクローラー向けのルートはGETだけでなくHEADも成功させる
4か月前
favicon が外部サービスやディレクトリ表示に反映されないとき、/favicon.ico 自体が 200 でも、クローラーが最初に確認するルート URL の HEAD / や GET / が 4xx/405 を返していると、アイコン発見に失敗することがある。
特に API サーバーや MCP/JSON-RPC など「通常は POST だけを受ける」エンドポイントをドメインルートに置く場合、ブラウザやクローラー向けの通常 GET / と HEAD / には最小 HTML もしくは同等のヘッダーを 200 で返し、アイコン参照タグ(link rel=icon)や apple-touch-icon を発見できるようにする。
判断基準:
GET /は favicon link 付きの最小 HTML を返す。HEAD /も 200 とcontent-type: text/htmlなどの発見に必要なヘッダーを返し、本文は返さない。- プロトコル上意味のある特殊な GET(例: SSE の
Accept: text/event-stream)は既存仕様を維持する。 - 未知パスや本来拒否すべきメソッドまで一律 200 にしない。発見性のための例外はルートとアイコンパスに限定する。
検証方法は、外部 favicon サービスだけを見るのではなく、まずルート(/)への HEAD と GET、および /favicon.ico への HEAD を順に叩き、配信側が 2xx を返すか確認する(curl の -I/-i で確認できる)。外部サービスがまだ古い結果を返す場合は、そのサービスのキャッシュや再クロール待ちとして切り分ける。
Google s2 favicon は http:// キーで内部キャッシュする — bare domain は http に寄り、http 側がクロールされるまで更新されない
4か月前
Google の s2 favicon 取得エンドポイントは、裸のドメインを domain パラメータで渡すと、内部の faviconV2 では http スキームの URL キーへ正規化されることがある。サイト本体が HTTPS canonical で、HTTP から HTTPS へ正常に恒久リダイレクトしていても、Google 側の favicon キャッシュは http キーと https キーで反映状態が別々に見える。
実例として、HTTPS 側は正しい新アイコンを返すのに裸ドメイン指定(=http キー)だけが古いまま、という状態が長く続いた。最終的な原因は「http スキーム側の URL が favicon 専用クローラにクロールされていなかった」こと。Google は内部的に http の URL キーで favicon をキャッシュしており、http 側が再クロールされるまで裸ドメインの結果は更新されなかった。http 側がクロールされたタイミングで反映された。つまり、リダイレクト設定が正しくても、favicon の反映は http キーのクロール待ちに律速されうる。
判断基準
- 自分のアプリや検証コードで Google favicon API を呼ぶなら、裸ドメインではなく scheme 付きの URL を渡す。具体的には domain_url パラメータ、または domain に scheme 付き URL を渡せる経路を使い、HTTPS canonical の favicon キャッシュを見る。
- 裸ドメインの結果が古い/デフォルトアイコンでも、scheme 付き HTTPS URL の結果が正しいなら、配信ファイル自体は採用可能で、問題は外部キャッシュの URL キー差分(http キーの未反映)として切り分ける。
- 裸ドメイン表示まで揃えたい場合は、HTTPS だけでなく http スキーム側の URL(ルートと favicon パス)が、favicon 専用クローラに発見・取得される状態になっているかを確認する。https へ恒久リダイレクトしていても、リダイレクト元の http URL 自体が一度クロールされないと http キーのキャッシュは更新されない。
- Search Console で再クロールを依頼する対象は canonical の HTTPS ホームページにするが、これはページのインデックス更新であって favicon 専用クローラの http キー再取得を早める手段ではない。favicon は別系統で遅延しうる(インデックスとクロール系統が分かれている既存知見を参照)。公式に即時反映させる手段はなく、http 側のクロール待ちになることがある。
検証
外部から通常の取得と Googlebot / Googlebot-Image 相当の取得を行い、http ホームページ・favicon・アイコン本体がすべて 1 回の恒久リダイレクトで HTTPS の正常応答へ到達するかを見る。次に Google favicon キャッシュで裸ドメイン指定(http キー)と scheme 付き HTTPS 指定のレスポンスを比べる。HTTPS 指定だけ正しい場合は、サイト配信ではなく Google 側 http キーの favicon キャッシュ(=http 側クロール待ち)として扱う。
Google の favicon はインデックスと別系統のクロール、別ホスト比較で更新待ちを切り分ける
4か月前
サイトの favicon を差し替えたのに、検索結果や favicon プロキシ(検索エンジンが提供する domain 指定の favicon 取得エンドポイント)が古いまま/汎用の地球儀アイコンのままになることがある。原因の切り分けに使える判断基準。
クロール系統が分かれている
- favicon の取得・反映は、ページのインデックス用クローラとは別系統の favicon 専用クローラが担い、インデックス更新より数日〜数週間遅れて反映されることが普通にある。
- サーチコンソール等で URL 検査・インデックス登録をしても、更新されるのはページのインデックスであって favicon の再取得は早まらない。「クロール許可=はい/ページ取得=成功/インデックス済み」でも favicon は別物として遅延しうる。
- favicon プロキシや検索結果の favicon は、ホスト(サブドメインを含む)単位で独立キャッシュされる。あるホストで新アイコンが反映されても、同じ実体ファイルを使う別ホストには自動波及しない。
ファイル無効かクロール遅延かの切り分け
- 古いまま更新されない時、原因は「ファイル自体が要件未達などで採用されていない」か「単なる再クロール待ち」のどちらか。
- 同一の favicon 実体ファイルを配信している別ホストの favicon プロキシを引き、そこで新アイコンが出ているかを見る。別ホストで採用済みなら、ファイルは有効で当該ホストはクロール待ち確定(待つしかない)。別ホストでも古い/汎用アイコンなら、ファイル側(発見性・サイズ要件など)を疑う。
- サイズ要件(例: 推奨サイズの有無)が原因かを疑う前に、同一ファイルが別ホストで採用されている事実があれば、サイズは原因でないと断定でき、要件強化の作業を無駄に行わずに済む。
比較時の注意
- ICO 実体ファイルと、プロキシが返す PNG はエンコードが異なるため、バイナリのハッシュは必ず食い違う。ハッシュ比較で同一性を判断せず、画像を目視で見比べる。
- 確実に再取得を早める公式手段はない。発見性(ルートとアイコンパスが取得可能か)とファイル有効性を潰した上で待つ。3〜4週間しても来なければ、別ファイル名へ差し替えて新規リソースとして認識させる手段を検討する。