PR
【GatsbyJS製ブログ】MDXの記事に画像を表示(gatsby-plugin-imageの利用法も)
こちらの記事で、MDXの書き方について説明しましたが、この記事ではMDX内で画像を表示する方法を説明します。
簡単に画像指定することもできますが、せっかくGatsbyを使っているので、画像最適化プラグインgatsby-plugin-imageをMDX内で使う方法も説明します。
- Gatsbyでブログを書いてるけど、画像の貼り方がわかんない
- gatsby-plugin-imageをMDX内で使えるの?使い方は?
まずは普通に画像指定する
こちらはマークダウン形式でも可能な画像指定方法です。
![代替テキスト](画像URL)
これでいけます。
ただ、これは楽なのですが、pngならpng、jpgならjpg、といった感じでそのままの画像フォーマットで表示されます。
「なにを当たり前のことを…」と思うのですが、Gatsbyのウリの一つに「画像最適化」があります。
これは、gatsby-plugin-imageというプラグインを使わなければならないのですが、このプラグインを使うことで自動的にフォーマットを変えてくれたりします。
これにより、さらに速いサイトの表示速度を実現しています。
ただ、これをMDX内で使うのに苦戦したので、以下で使い方を説明します。
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が使えるので、ぜひ検討してみてください。
Gatsbyを学習している方への私からのオススメ!
私が読んでよかったな、と思うGatsbyの学習をするのにオススメの本を紹介しておきます。
画も多くてとても読みやすく、ステップバイステップでGatsbyJSのサイトを作ることができます!
また、Gatsbyを学習する上で、Reactを同時に学習することもオススメします。
こちらも、まず構成や見た目がとても読みやすい本です。加えてReactに対しての専門的な知識を丁寧に学ぶことができます。ここでReactに対する基礎知識をしっかりしておくと、Gatsbyに対する見方が変わって、Webページをサクサク作ることができるようになります!
あと、色々と調べたのですが、Reactの学習ならUdemyもオススメです。必要な知識を1動画単位で購入できるので、学習に無駄がないです。Reactってあんまり学習できるプログラミングスクールみたいなのがないんですよね…。「React」と検索するだけで大量に動画がでてきます!