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

2 min read
hiroweb developer

背景

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

developer.mozilla.orgurl() - CSS: カスケーディングスタイルシート | MDNurl() は CSS の関数で、ファイルを含めるために使用します。引数は絶対 URL、相対 URL、Blob URL、データ URL の何れかです。 url() 関数は attr() 関数のように、他の CSS 関数に引数として渡すことができます。値を使用するプロパティに応じて、求められるリソースは画像、フォント、スタイルシートの何れかになります。url() 関数表記は <url> データ型の値になります。

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)))を利用する。