Remixアプリでfaviconの<link>タグを直接app/root.tsxに貼り付けて、Remixが重複を削除したり、静かに無視したりするのを経験したなら、正しいパターンはlinksエクスポートです。Remix v2では、HTMLのリンク記述子をここに置くことが期待されており、フレームワークがそれらをドキュメントのheadにレンダリングします。(完全なAPIサーフェスについては、公式のRemixルートlinksドキュメントを参照してください。)
前提条件
動作するRemix v2プロジェクトと、一連のfaviconファイルが必要です。最新の完全なセットには、以下を用意してください:
/public/favicon.svg— ベクターソース。ダークモード対応/public/favicon.ico— 古いブラウザ向けのレガシーフォールバック/public/apple-touch-icon.png— iOSホーム画面用の180×180ピクセル/public/site.webmanifest— PWAインストール動作用
public/に置いたファイルはサイトルートから提供されるため、/public/favicon.svgは追加のルーティングなしでhttps://yoursite.com/favicon.svgとして解決されます。
ステップ1: root.tsxでlinksエクスポートを構築する
linksエクスポートは、<link>記述子の配列を返す関数です。Remixは各記述子をドキュメントのhead内の実際のHTMLタグにマッピングします。適切な型付けのために、@remix-run/node(またはランタイム固有のパッケージ)からLinksFunctionを使用してください。
import type { LinksFunction } from '@remix-run/node';
export const links: LinksFunction = () => [
{ rel: 'icon', href: '/favicon.svg', type: 'image/svg+xml' },
{ rel: 'alternate icon', href: '/favicon.ico', type: 'image/x-icon' },
];
relの値はHTML仕様に直接対応します。完全な語彙については、whatwgのrel=icon定義を参照してください。ブラウザは現在のコンテキストに一致する最初のアイコンを選択するため、シャープなSVGをICOフォールバックの前にリストしてください。
ステップ2: Apple Touchとマニフェストのエントリを追加する
Remixはリソースタイプに関係なく、すべての記述子を同じ方法で扱います。それらを同じ配列にスタックしてください:
export const links: LinksFunction = () => [
{ rel: 'icon', href: '/favicon.svg', type: 'image/svg+xml' },
{ rel: 'alternate icon', href: '/favicon.ico', type: 'image/x-icon' },
{ rel: 'apple-touch-icon', href: '/apple-touch-icon.png', sizes: '180x180' },
{ rel: 'manifest', href: '/site.webmanifest' },
];
sizes属性は情報提供用です。ブラウザは特定のレンダリングコンテキストに最適なものを選ぶ際にこれを参照します。Remixエクスポート以外のより広範なfaviconリンクタグパターンについては、favicon HTMLコード例を参照してください。
ステップ3: ダークモードSVGをクリーンに配信する
ブラウザはアイコンリンクタグのmediaを尊重します。2つのSVGを配信し、ユーザーのカラースキームに基づいてブラウザに適切な方を選択させることができます。2番目のファイルを/public/favicon-dark.svgとして保存し、両方の記述子を追加してください:
{
rel: 'icon',
href: '/favicon.svg',
type: 'image/svg+xml',
media: '(prefers-color-scheme: light)',
},
{
rel: 'icon',
href: '/favicon-dark.svg',
type: 'image/svg+xml',
media: '(prefers-color-scheme: dark)',
},
HTML仕様はアイコンリンクのmedia記述子を明示的にサポートしているため、これはハックではなく第一級のパターンです。これらのファイルが正しく切り替わるためのSVG側の設定については、faviconダークモードガイドでメディアクエリ構文を詳しく説明しています。
ステップ4: アイコン更新時にキャッシュをバストする
ブラウザはfavicon.icoを積極的にキャッシュし、Remixはデフォルトでpublic/アセットにコンテンツハッシュを追加しません。新しいデザインをリリースする際は、バージョンクエリ文字列を追加してください:
{ rel: 'icon', href: '/favicon.svg?v=2', type: 'image/svg+xml' }
アイコンをリリースするたびにvの値を増やしてください。URLに紐づくキャッシュが更新され、ユーザーはすぐに新しいタブグラフィックを表示できます。
よくある落とし穴
Remixのlinksエクスポートでアイコンを配線する際は、以下に注意してください:
- 生のJSXにタグを置く。
root.tsxの<head>内に書かれたタグはレンダリングされますが、Remixの重複排除とSSRの順序付けにより、静かに削除される可能性があります。エクスポートが文書化されたパスです。 typeを忘れる。MIMEヒントがないと、Safariが誤った形式を選択することがあります。image/svg+xmlとimage/x-iconが安全なデフォルトです。shortcut iconを使用する。このレガシー属性はHTML仕様の一部ではなく、最新のブラウザは無視します。代わりにalternate iconを使用してください。- マニフェストの
relをスキップする。PWAインストールはアイコンリンクではなくsite.webmanifestから読み取ります。同じlinks配列から参照してください。 - デプロイ後にアイコンが古いまま。ブラウザキャッシュはデプロイを生き延びます。アイコン更新時には必ずキャッシュバストを行ってください。
まとめ
Remixのlinksエクスポートは、favicon HTMLタグを配線する最もクリーンな場所です。型安全性、予測可能なSSR出力、そしてアイコンスタックを更新する際に編集する単一ファイルが得られます。Mzu favicondlのシャープなベクターソースと組み合わせ、キャッシュバストクエリを配信すれば、Remixアプリはすべてのブラウザタブでプロフェッショナルに見えます。