SVG ファビコンのファイル名を `favicon.ico` にして <link rel="icon"> を省略する

投稿

ファビコンを /favicon.ico のファイルパスでルートディレクトリに置くとブラウザが勝手に読みに行ってくれますが、 PNG や SVG などのファイル形式の場合は HTML 内に <link rel="icon"> を指定する必要がある……と思い込んでいました。すなわち ICO フォーマットでファイルパスが /favicon.ico の場合は

<link rel="icon" href="/favicon.ico" type="image/vnd.microsoft.ico" />

を書いても書かなくても大丈夫ですが、 /favicon.svg の場合に

<link rel="icon" href="/favicon.svg" type="image/svg+xml" />

を省略することはできません。もし省略するとブラウザは /favicon.ico を読みに行ってしまい(そのファイルが存在するか否かに関わらず)、 SVG 画像は無視されます。

ところが先日、 Implement favicon.svg fallback · Issue #6957 · whatwg/html(github.com) を読んでいてハッとさせられました。長くない Issue なのでぜひ原文を読んでいただければと思いますが、一応要約すると

  • 現在の HTML 仕様では(<link rel="icon"> を書かずとも)/favicon.ico にフォールバックすることを規定している
  • しかしラスター画像では様々な環境に対応するために数十ものアイコンを用意(realfavicongenerator.net)することが Web 開発の現場では見られる
  • そのため現行のフォールバックを維持しつつ、ベクター画像の favicon.svg へのフォールバックを追加してはどうか
  • favicon.icoimage/svg+xml として配信することも可能だろうが、ハック的な手法でありベストプラクティスとして推進したいものではない

という提案に対し、 Domenic 氏がこんな返答をしています。

Yeah, in general we don't care about file extensions on the web; the fact that we requested /favicon.ico instead of /favicon is a historical accident stemming from how this was first implemented and deployed, and not meant as an endorsement that the file has to be in Windows icon format.

whatwg/html の Issue #6957 に対する 2021年8月13日 4:53 JST のコメント(github.com)

なるほど、これは盲点でした。歴史的な経緯[1]により、デフォルトのファイル名は favicon.ico と決まっているもの、ファイルフォーマットまで定まっているわけではありません。 .ico の拡張子で実体を PNG や SVG にすることは、ローカルマシン上ではハック的な手法と言えるでしょうが、ウェブにおいてはサーバー設定で MIME を正しく設定すればとくに問題ありません。

念のため HTML 仕様を確認してみると、ファビコンは 4.6.6.8 Link type "icon"(html.spec.whatwg.org) の節で以下のような言及がありますが、やはり定められているのはファイルパスだけで、フォーマットが ICO でなければならないとはどこにも書かれていません。

In the absence of a link with the icon keyword, for Document objects whose URL's scheme is an HTTP(S) scheme, user agents may instead run these steps in parallel:

1. Let request be a new request whose URL is the URL record obtained by resolving the URL "/favicon.ico" against the Document object's URL, client is the Document object's relevant settings object, destination is "image", synchronous flag is set, credentials mode is "include", and whose use-URL-credentials flag is set.

2. Let response be the result of fetching request.

3. Use response's unsafe response as an icon as if it had been declared using the icon keyword.

4.6.6.8 Link type "icon"(html.spec.whatwg.org)

というわけで、環境によってアイコンを出し分けするようなことをせず、一つのファイルで済ませる場合は以下のいずれかの方針をとる事になるでしょう。

  • ファイルフォーマットに合わせた拡張子ないし拡張子なしとし、 HTML 内に <link rel="icon"> で指定する。ファイルパスは /favicon.ico に限らず /image/icon.svg?v=1.0.0 など自由に設定可能。
  • ファイルフォーマットに関わらずパスを /favicon.ico 固定とし、サーバー設定で適切な MIME を指定する。 <link rel="icon"> は省略可能。

後者の方法を採用する場合、 PNG ならとくに問題はないと思うのですが、 SVG 形式だと現状 Safari 15 が SVG Favicon に未対応な点には注意したいところです。当ブログではその点を承知のうえで後者の方法に変更し、 <link rel="icon"> を除去しました。