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

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

- Gatsbyでブログを書いてるけど、画像の貼り方がわかんない
- gatsby-plugin-imageをMDX内で使えるの?使い方は?
まずは普通に画像指定する
こちらはマークダウン形式でも可能な画像指定方法です。

これでいけます。

ただ、これは楽なのですが、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を加工していく
以下の二つを変更していきます。
- frontmatterに使う画像を書き並べていく
- 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点を加工していきます。
- MDXRendererで上記のlocalImagesをpropsとして渡す。
- 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を使うイメージとしては次のような感じでしょうか。





自分のfrontmatterに画像URLを持ってるくせに、外から渡してもらわないといけないイメージですね。まぁ、MDXRendererで展開するので、その辺は仕方ない気もしますが…直感には反します。
まとめ
MDX内で画像を呼び出す方法を2パターン説明しました。
単純に呼び出すだけなら簡単なのですが、せっかくなのでGatsbyの利点を活かしていきたいところです。
最初に数カ所加工するだけでgatsby-plugin-imageが使えるので、ぜひ検討してみてください。




最近本格的にCSSの勉強を始めました。
WordPressでもGatsbyJSでも必要な基本的な知識「CSS」…これが奥深い。



もちろんCSSに関する基本的な知識はあるのですが、引き出しは多くしておきたいものです。
ワンランク上のホームページ、ブログ作成を目指して、特に「これはよかった」というオススメのCSS学習教材の紹介をしていきます。
動画編
Webデザインのオンラインスクールなどは沢山ありますが、数万円〜数十万円するので、なかなかハードルが高いですよね。
そこでオススメなのはUdemy。
このブログでもちょくちょく紹介させてもらっていますが、一つの講座買い切り、というのがありがたいです。
しかも、種類もかなり豊富!GatsbyJSの講座まである、というのは他ではなかなかないです。
そのなかでもオススメのCSSに関する講座を紹介しておきます。



CSSの講座とかは沢山あるので、「これよさそう!」と思ったものを探すのも楽しいかもしれません。
書籍編
CSSを実践的に書いていくなら、書籍も便利です。
本を片手にコーディング、というのは効率もいいですよね。
こちらもオススメの本を紹介しておきます。



CSSの基本ができている人が「次のステップに行きたいなぁ…」というときにオススメです。