[React] SVGコンポーネントをCSS in JSの`background:url()`などで利用する方法

2 min read

背景

CSS in JS を利用したコンポーネント内で定義したurl()background: url()content: url())で SVG コンポーネントの内容を指定したい。

developer.mozilla.org<url> - CSS: カスケーディングスタイルシート | MDN<url> は CSS のデータ型で、リソースを指します。リソースには画像、動画、CSS ファイル、フォントファイル、SVG 機能などがあります。

SVG コンポーネントが <svg>〜</svg>を提供していれば話が早いのだが、レンダーされるまでそれが取得できない場合に以下の内容を試みた。

環境

  • react: 18.2.0
  • react-dom: 18.2.0
  • react-icons: 4.7.1

コード

renderToStringを利用するとコンポーネントをstringで取得できる。

ReactDOMServer.renderToString(<Component />);

下記は、React Icons から任意の SVG コンポーネントを CSS in JS 内で利用したコード。

import { RxExternalLink } from "react-icons/rx";

const IconExternalLink = () => {
  const SVG = ReactDOMServer.renderToString(<RxExternalLink size={16} />);
  return "data:image/svg+xml," + encodeURIComponent(SVG);
};

const Component = styled.div`
  &::before {
    display: block;
    content: url(${IconExternalLink});
  }
`;

SVG コンポーネントを CSS のurl()で読み込めるように、renderToStringstringにしてencodeURIComponentしたものを指定している。


Base64 形式に変換したものを指定したい場合は下記のような指定をする。

return "data:image/svg+xml;base64," + Buffer.from(SVG).toString("base64");

Node.js 上で SVG コンポーネントを Base64 エンコードする場合はBuffer.from(string).toString("base64")を利用。ブラウザ上で実行する場合はbtoa(unescape(encodeURIComponent(string)))を利用する。