1. インライン SVG コンポーネント
各アイコンをコンポーネントに変換する方法(このサイトが自動化している方法)なら、すべてを制御できます。アイコンは currentColor で色を継承し、size や className などの props を受け取り、CSS やアニメーションライブラリで動かせます。バンドラーは未使用のコンポーネントをツリーシェイキングで除外するので、インポートしたアイコンだけが配信されます。
その代わり、マークアップは JavaScript バンドルの一部になります。小さなアイコンが数十個程度なら影響はわずかですが、複雑なイラストが数百個となると話は別です。
2. img タグと CSS 背景
<img src="/logo.svg" alt="会社名"> は最もシンプルな方法で、ブラウザがファイルをキャッシュできます。ただし SVG は CSS から切り離されるため、ホバー時やダークモードで色を変えることはできません。変化しないロゴやイラストに向いています。
3. SVGR とビルド時ローダー
SVGR(@svgr/webpack や vite-plugin-svgr 経由)は、ビルド時に .svg のインポートをコンポーネントに変換します。大量のアイコンフォルダには便利ですが、ビルド設定が増え、バンドラーや Turbopack によって挙動が異なる場合があります。このツールで一度変換すれば、同じ種類のコンポーネントをソースコードとしてコミットできます。
4. SVG スプライトと 5. アイコンライブラリ
スプライトは多数の <symbol> 要素を 1 つのファイルにまとめ、<use href="#icon"> で参照する方法です。HTML を小さく保てますが、サーバーサイドレンダリングが複雑になります。Lucide、Heroicons、Phosphor などのアイコンライブラリは完成済みのコンポーネントを提供しており、スタイルがデザインに合うなら理想的です。
どの方法を選ぶにしても、次のアクセシビリティのルールを守りましょう。
- テキストに添える装飾的なアイコンには aria-hidden="true" を付ける。
- アイコンだけのボタンなど単独で使うアイコンには、ボタンの aria-label か SVG 内の <title> でアクセシブルな名前を付ける。
- viewBox を残し、アイコンのサイズを em や rem で指定して、ユーザーの文字サイズに合わせて拡大縮小させる。
- 意味を持つアイコンは 3:1 以上のコントラスト比を確保する(WCAG 1.4.11)。