【GatsbyJS製ブログ】MDXの記事に画像を表示(gatsby-plugin-imageの利用法も)

PR

こちらの記事で、MDXの書き方について説明しましたが、この記事ではMDX内で画像を表示する方法を説明します。

簡単に画像指定することもできますが、せっかくGatsbyを使っているので、画像最適化プラグインgatsby-plugin-imageをMDX内で使う方法も説明します。

この記事はこんな人にオススメ
  • Gatsbyでブログを書いてるけど、画像の貼り方がわかんない
  • gatsby-plugin-imageをMDX内で使えるの?使い方は?
目次

まずは普通に画像指定する

こちらはマークダウン形式でも可能な画像指定方法です。

![代替テキスト](画像URL)

これでいけます。

マークダウンで画像指定

ただ、これは楽なのですが、pngならpng、jpgならjpg、といった感じでそのままの画像フォーマットで表示されます。

「なにを当たり前のことを…」と思うのですが、Gatsbyのウリの一つに「画像最適化」があります。

これは、gatsby-plugin-imageというプラグインを使わなければならないのですが、このプラグインを使うことで自動的にフォーマットを変えてくれたりします。

これにより、さらに速いサイトの表示速度を実現しています。

クマ

ただ、これをMDX内で使うのに苦戦したので、以下で使い方を説明します。

BearFruitのマスコットキャラ「クマ」がLINEスタンプになりました!

プログラマーの心に刺さる、「プログラミングあるある」。毎日使いたくなること間違いなし!

gatsby-plugin-imageを使う

詳細は省きますが、gatsby-plugin-imageは静的に画像指定をするStaticImageと動的に画像指定をするGatsbyImageという二つの表示の方法があります。

  • StaticImage → 画像の配置場所と配置する画像が決まっているとき、直接画像指定をして使う。
  • GatsbyImage → テンプレートなどで使う画像が変わるとき(例えば記事ごとに異なる、アイキャッチなど)にGraphQLを使って表示しないといけないときに使う。
クマ

記事によって使う画像は決まってるんだからStaticImageでよくね?

ということで、MDX内に、

import {StaticImage} from 'gatsby-plugin-image';

…
<StaticImage src="./photo1.JPG" alt="写真だよ">
…

のような感じでStaticImageを使おうとしたのですが、上手くいきませんでした

クマ

なぜ…

結論から言うと、GatsbyImageを使うことで解決しましたが、frontmatterとMDXRendererの方にも手を加える必要があります

MDXを加工していく

以下の二つを変更していきます。

  1. frontmatterに使う画像を書き並べていく
  2. gatsby-plugin-imageからGatsbyImageをインポートして、画像を表示させたい位置で使う。

まずはMDX内のfrontmatterに、次のような感じで使う画像を書き加えていきます。

---
title: タイトルだよ
…
embeddedImagesLocal: //←こんな感じのfrontmatterを加える。名前は適当でよい
    - './photo1.JPG' //↓以下にこの要領で使う画像ファイルを書き並べていく。これが配列として渡される。どんな形の配列かは後述。
    - './photo2.JPG'
    - './photo3.JPG'
---

そして、MDX内の画像を表示したい部分にGatsbyImageを使います。

import {getImage, GatsbyImage} from 'gatsby-plugin-image';

…
<GatsbyImage alt='駐車場にて' image={getImage(props.localImages[0])}/> //frontmatterで定義した配列の最初、つまりphoto1.JPGが表示される。
//↑こんな感じ。getImageはGraphQLで取得したデータを表示するために使う、くらいの認識で。props.localImages[0]については後述。
…

MDX全体のイメージは次のようになります。

---
title: タイトルだよ
date: "2022-04-05T22:00:00.121Z"
…
embeddedImagesLocal:
    - './photo1.JPG'
    - './photo2.JPG'
    - './photo3.JPG'
---

import {getImage, GatsbyImage} from 'gatsby-plugin-image';

…
(記事本体)
<GatsbyImage alt='駐車場にて' image={getImage(props.localImages[0])}/>
…

MDXRendererを加工していく

こちらの記事で紹介しましたが、MDXを展開する部分があるはずです(blog-post.jsとか)。ここを加工していきます。

こちらも以下の2点を加工していきます。

  1. MDXRendererで上記のlocalImagesをpropsとして渡す。
  2. localImagesに渡す用の画像データ群をGraphQLでfrontmatterから取ってくる。

まずはMDXRendererで「localImages」を渡すように加工します。

…
<MDXRenderer
  frontmatter={post.frontmatter}
  itemProp="articleBody"
  localImages = {post.frontmatter.embeddedImagesLocal}
  //↑これを加える。これで、props.localImagesにGraphQLでとってきたMDX内の画像データ達が配列として渡される。
>
  {post.body}
</MDXRenderer>
…

次にlocalImgesに渡すための画像データ達をGraphQLでとってきます。

export const pageQuery = graphql`
  query BlogPostBySlug(
    $id: String!
    $previousPostId: String
    $nextPostId: String
  ) {
    …
    mdx(id: { eq: $id }) {
      id
      …
      frontmatter {
        title
        date(formatString: "MMMM DD, YYYY")
        …
        //以下の記述をfrontmatter内に加える
        embeddedImagesLocal { //MDX内で加えたfrontmatter
          childImageSharp{
            gatsbyImageData
          }
        }
        //ここまで
        …

以上、MDXとMDXRendererを加工することで、無事gatsby-plugin-imageを通して、画像をMDX内で使うことができるようになりました。

gatsby-plugin-imageをMDX内で使用
クマ

単純にマークダウンでの画像呼び出し(上)とgatsby-plugin-imageでの呼び出し(下)を並べてみました。

MDX内でgatsby-plugin-imageを使うイメージとしては次のような感じでしょうか。

MDXでgatsby-plugin-imageを使うイメージ
クマ

自分のfrontmatterに画像URLを持ってるくせに、外から渡してもらわないといけないイメージですね。まぁ、MDXRendererで展開するので、その辺は仕方ない気もしますが…直感には反します。

まとめ

MDX内で画像を呼び出す方法を2パターン説明しました。

単純に呼び出すだけなら簡単なのですが、せっかくなのでGatsbyの利点を活かしていきたいところです。

最初に数カ所加工するだけでgatsby-plugin-imageが使えるので、ぜひ検討してみてください。

Gatsbyを学習している方への私からのオススメ!

私が読んでよかったな、と思うGatsbyの学習をするのにオススメの本を紹介しておきます。

画も多くてとても読みやすく、ステップバイステップでGatsbyJSのサイトを作ることができます!

また、Gatsbyを学習する上で、Reactを同時に学習することもオススメします。

こちらも、まず構成や見た目がとても読みやすい本です。加えてReactに対しての専門的な知識を丁寧に学ぶことができます。ここでReactに対する基礎知識をしっかりしておくと、Gatsbyに対する見方が変わって、Webページをサクサク作ることができるようになります!

あと、色々と調べたのですが、Reactの学習ならUdemyもオススメです。必要な知識を1動画単位で購入できるので、学習に無駄がないです。Reactってあんまり学習できるプログラミングスクールみたいなのがないんですよね…。「React」と検索するだけで大量に動画がでてきます!

あなたへオススメ!
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次