gatsby-imageでsvgを使う

4 min read読了の目安(約2500字

gatsby-imageでsvgを使おうとしたときにハマったのでメモ

問題

svgを他の拡張子(png,jpg)の画像を同じように取得して、gatsby-imageで表示しようとしても表示できない。

const Index = () => {
  const images = useStaticQuery(graphql`
    query {
      file(relativePath: { eq: "like.svg" }) {
        childImageSharp {
          fluid {
            ...GatsbyImageSharpFluid
          }
        }
      }
    }
  `);
  return (
    <div>
      <Img fluid={images.file.childImageSharp.fluid} />
    </div>
  );
};

解決方法

svgを使う場合はchildImageSharpではなく、publicURLを取得してimgタグで表示する。

const Index = () => {
  const image = useStaticQuery(graphql`
    query {
      file(relativePath: { eq: "like.svg" }) {
        publicURL
      }
    }
  `);
  const { publicURL } = image.file;
  console.log(publicURL); ///static/e152474a47557a24b12490f46840ebb7/like.svg
  return (
    <div>
      <img src={publicURL} width="100px" height="100px" alt="like" />
    </div>
  );
};

ちゃんと表示できました。やったね😘

gatsby-imageはsvgをサポートしていない

issueを見ていると、

gatsby-plugin-sharp / gatsby-image doesn't handle SVGs or GIFs. The fluid query (in your case) creates multiple images from 0px to 1060px (+ bigger sizes for retina). That wouldn't make sense with SVGs as they're vector files and don't need different sizes - they can scale indefinitely without loss of quality.

というコメントがあった。
意訳すると、gatsby-plugin-sharpとgatsby-imageはsvgとgifを取り扱わない。fluid queryは0pxから1060pxの複数の画像を生成するが、svgはベクター画像(拡大縮小しても画質が変わらない画像)なのでその必要がない。
ということ。
つまり、svg形式を受け付けていないqueryを投げたのでnullが帰ってきたってことらしい。

そもそもgatsby-image, gatsby-plugin-sharpとは

そもそも雰囲気でこれらのライブラリを使っていた気がするのでさらっと調べてみた

gatsby-plugin-sharp

Sharpという画像処理ライブラリをベースとした画像処理機能を提供するプラグインらしい。他のGatsby pluginsから利用されている低レベルのヘルパーという位置づけらしい。

Sharpとは

大きな画像を様々なサイズのJPEG,PNG,WebP画像に変換するライブラリらしい。

gatsby-image

GatsbyのGraphQL queriesを用いて、画像ローディングの最適化を行うライブラリ。画像の変換にgatsby-plugin-sharpを使っている。

感想

最初から各ライブラリがどういうものかしっかり読んでいれば回避できそうなエラーだった。
でも最初からライブラリの概要読むのめんどくせー😩

参考文献