React環境で手軽にSVGを表示する方法

JavaScript

ダウロードしたSVGを手軽にReactアプリケーション上で表示する方法について書きました。
今回は以下の3つの方法について紹介します。

  • ReactComponentとしてインポートする
  • imgタグで呼び出す
  • react-svgを利用する

なお、今回紹介するサンプルコードではGoogle FontsのSVGを利用します。

ReactComponentとしてインポートする

Create React APP『Adding SVGs』で紹介されている方法です。
import { ReactComponent as Xxx } のようにするとSVGをコンポーネントとしてインポートできます。

App.tsx

import { ReactComponent as HomeIcon } from "../public/images/home.svg";
import { ReactComponent as FilledHomeIcon } from "../public/images/filledHome.svg";
import styles from "./App.module.css";

export default function App() {
  return (
    <>
      {/* プロパティの指定方法 */}
      <HomeIcon width={24} height={24} />
      {/* styleを直接記述する方法 */}
      <HomeIcon style={{ width: "24px", height: "24px", fill: "blue" }} />
      {/* CSSを適用する方法 */}
      <HomeIcon className={styles.icon} />

      {/* 『Fill: 0』のアイコンのfillの色を変更した例 */}
      <HomeIcon width={48} height={48} fill={"red"} />
      {/* 『Fill: 1』のアイコンのfillの色を変更した例 */}
      <FilledHomeIcon width={48} height={48} fill={"red"} />

      {/* SVGで指定できる様々なプロパティ */}
      <FilledHomeIcon
        width={48}
        height={48}
        fill={"red"}
        stroke={"yellow"}
        strokeWidth={2}
      />
    </>
  );
}

App.module.css

.icon {
  width: 24px;
  height: 24px;
}

参考: 『Module ‘”*.svg”‘ has no exported member ‘ReactComponent’』というエラーが出た場合

TypeScript環境ではimport { ReactComponent as HomeIcon } from "../public/images/home.svg";の箇所でModule '"*.svg"' has no exported member 'ReactComponent'. Did you mean to use 'import ReactComponent from "*.svg"'というエラーが出るケースがあります。

上記のエラーは型定義ファイル(d.tsファイル)を更新すると解決できます。

index.d.ts

declare module '*.svg' {
  import React = require('react');
  export const ReactComponent: React.FC<React.SVGProps<SVGSVGElement>>;
  const src: string;
  export default src;
}

型定義ファイルを新規追加した場合はtsconfig.jsoninclude項目に当該ファイルを追加します。

tsconfig.json

{
  (略)
  "include": [
    "next-env.d.ts",
    "**/*.ts",
    "**/*.tsx" // 追加
  ]
}

なお、型定義ファイルの詳細解説は【TypeScript】アンビエント宣言(declare)と型定義ファイル(d.ts)の概要で紹介しています。

imgタグで呼び出す

SVGを画像ファイルとして読み込む方法です。

App.tsx

import styles from "./App.module.css";

export default function App() {
  return (
    <>
      {/* プロパティの指定方法 */}
      <img src="images/home.svg" width="24" height="24" alt="ホームアイコン" />
      {/* CSSを適用する方法 */}
      <img src="images/home.svg" className={styles.icon} alt="ホームアイコン" />
    </>
  );
}

react-svgを利用する

react-svgを利用することでSVGをコンポーネントのように扱えます。

App.tsx

import { ReactSVG } from "react-svg";
import styles from "./App.module.css";

export default function App() {
  return (
    <>
      {/* styleを直接記述する方法 */}
      <ReactSVG
        style={{ width: "24px", height: "24px", fill: "blue" }}
        src="images/home.svg"
      />
      {/* CSSを適用する方法 */}
      <ReactSVG className={styles.icon} src="images/home.svg" />
    </>
  );
}

さいごに

Next.js環境でSVGを利用する場合はbabel-plugin-inline-react-svgを利用する方法もあります。詳細はNext.jsでSVGを利用する方法(babel-plugin-inline-react-svgの使い方)で紹介しています。

Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!

参考資料