本文へスキップ
SvgJsx
言語: 日本語

React で SVG アイコンを使う方法

React アプリに SVG アイコンを組み込む一般的な方法は 5 つあります。このガイドではパフォーマンス、スタイリング、アクセシビリティの観点から比較し、それぞれが適した場面を紹介します。

クイックプリセット:
.svg ファイルをここにドロップ、またはファイルは FileReader でローカルに読み込まれ、アップロードされることはありません。
オプション
エクスポート:
import type { SVGProps } from "react";

const HeartIcon = ({ size = 24, ...props }: SVGProps<SVGSVGElement> & { size?: number | string }) => (
  <svg viewBox="0 0 24 24" className="icon icon-heart" width={size} height={size} {...props}>
    <g id="Layer_1" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M19.0001 14.0002c1.4900-1.4600 3.0000-3.2100 3.0000-5.5000A5.5000 5.5000 0 0 0 16.5000 3c-1.7600 0-3.0000.5000-4.5000 2-1.5000-1.5000-2.7400-2-4.5000-2A5.5000 5.5000 0 0 0 2 8.5000c0 2.3000 1.5000 4.0500 3 5.5000l7 7Z" style={{ fillOpacity: "0.15", fill: "currentColor" }} />
    </g>
  </svg>
);

export default HeartIcon;

プレビュー

変換後の SVG のプレビュー
元の SVG
706B
最適化後の SVG
548B(-22%)
コンポーネント
692B

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)。

よくある質問

React で SVG アイコンを使う最善の方法は?

UI アイコンなら、currentColor と size プロパティを備えたインラインコンポーネントが最も柔軟です。静的なアートワークには <img> を、スタイルが合うならアイコンライブラリを使いましょう。

インライン SVG アイコンはパフォーマンスに悪影響がありますか?

ほとんどありません。一般的な 24×24 のアイコンは最適化後 300〜600 バイト程度です。問題になるのは複雑なアイコンを数百個同時に描画する場合で、そのときはスプライトや <img> が適しています。

SVGR を使うべき?それとも手動で変換すべき?

SVGR は、頻繁に変わる大規模なアイコンセットと安定したビルドパイプラインがある場合に向いています。事前に変換したコンポーネントは設定不要で、どのバンドラーでも同じように動作します。

SVG アイコンをアクセシブルにするには?

装飾的なアイコンは aria-hidden="true" で隠し、意味のあるアイコンには aria-label や <title> でアクセシブルな名前を付けます。重要な情報をアイコンだけで伝えないようにしましょう。

Tailwind で SVG アイコンのサイズを指定するには?

固定の width と height を削除して viewBox を残し、size-5 や h-4 w-4 などのクラスを適用します。または size プロパティを有効にして数値を渡す方法もあります。