Gatsby上のMDX記事で画像のスライドショーを表示するための手順メモです。 gatsby-plugin-imagereact-responsive-carousel を使って実現してます。

昨日の記事で紹介した手順で作成した資産 に対して追加設定を行います。

1.ゴール

以下のような MDX ファイルでスライドショー表示ができるようにします。

---
slug: "test2"
title: "テスト"
images:
    - ./image-01.jpg
    - ./image-02.jpg
    - ./image-03.jpg
---
テストだよ

import SlideShow from '../../components/SlideShow'

<SlideShow images={props.frontmatter.images} interval={1000} autoPlay={true} infiniteLoop={false} />
  • frontmatter (MDXファイルの --- より上の部分) の images でスライドショー表示する画像を指定できる
  • SlideShow コンポーネントでスライドショー表示ができる
  • SlideShow コンポーネントは以下の属性を指定可能にする
    • images: スライドショー表示する画像ファイル
    • interval: スライドを送るタイミング
    • autoPlay: 自動的にスライドを送るかどうか
    • infiniteLoop: 無限ループするかどうか

2.プラグインの組み込み

gatsby-plugin-image とその必須コンポーネントおよび react-responsive-carousel をインストールします。

npm install gatsby-plugin-image gatsby-plugin-sharp gatsby-transformer-sharp react-responsive-carousel

gatsby-config.js に gatsby-plugin-image, gatsby-plugin-sharp, gatsby-transformer-sharp のプラグイン設定を行います。

module.exports = {
  plugins: [
    `gatsby-plugin-image`,
    `gatsby-plugin-sharp`,
    `gatsby-transformer-sharp`,
    (その他のプラグイン設定)
  ],
}

3.gatsby-node.js の修正

MDXファイルの frontmatter に記述した images のファイル情報を受け取れるように gatsby-node.js を設定します。

(省略)

  const result = await graphql(`
    {
      allMdx {
        edges {
          node {
            frontmatter {
              title
              slug
              images {
                childImageSharp {
                  gatsbyImageData
                }
              }
            }
          }
        }
      }
    }
  `)

(省略)

4.src/templates/blog-post.jsの修正

src/templates/blog-post.js のクエリ―でも images のファイル情報を受け取れるように修正します。

(省略)
export const pageQuery = graphql`
  query BlogPostBySlug($slug: String!) {
    mdx(frontmatter: { slug: { eq: $slug } }) {
      body
      frontmatter {
        title
        slug
        images {
          childImageSharp {
            gatsbyImageData(
              width: 300
              placeholder: BLURRED
              formats: [AUTO, WEBP, AVIF]
            )
          }
        }
      }
    }
  }
`
  • ここでは gatsbyImageDataのパラメタとして以下を指定しています。
    • width: 指定された幅の画像に変換する。ここでは300pxを指定。
    • placeholder: 実際の画像が読み込まれる前に表示される画像。ここではぼかし画像を指定。
    • formats: 生成する画像のタイプ。ここでは元画像のフォーマット(jpg / png), WebP, AVIF を指定。
  • gatsbyImageDataのその他のパラメタに関しては、gatsby-plugin-imageのリファレンス を参照。
  • gatsby-plugin-image を使うと gatsbyImageData で指定したパラメタに従って画像生成が行われ、以下のような picture タグを用いたHTMLに変換されます。このおかげで、より効率的な (サイズの小さい) 画像が自動的に選択されるようになります。
    <picture>
        <source type="image/avif" srcset="/static/.../abc.avif 75w, ...">
        <source type="image/webp" srcset="/static/.../abc.webp 75w, ...">
        <img  src="/static/.../abc.jpg" srcset="/static/.../abc.jpg 75w">
    </picture>

5.SlideShowコンポーネントの作成

src/components/SlideShow.js ファイルを作成します。

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

import 'react-responsive-carousel/lib/styles/carousel.min.css'
import { Carousel } from 'react-responsive-carousel'

const SlideShow = ({images, interval, autoPlay, infiniteLoop}) => {
    return (
      <div style={{width:'300px'}}>
        <Carousel showThumbs={false} infiniteLoop={infiniteLoop} autoPlay={autoPlay} interval={interval}>
          {images.map(i => ( <div><GatsbyImage image={getImage(i)} /></div>))}
        </Carousel>
      </div>
    );
}

export default SlideShow
  • 「react-responsive-carousel の Carousel コンポーネントの中に gatsby-plugin-image の GatsbyImage コンポーネントを並べる」というイメージの構成です。
  • GatsbyImage コンポーネントは、gatsby-plugin-image の説明においてはDynamic imagesとされているものに該当します。
  • Carouselの属性指定については react-responsive-carouselの説明 を参照ください。

6.SlideShowを利用する記事と画像を配置する

src/posts フォルダの下に一つフォルダを作ってその下に index.mdx という名前でファイルを作ります。 (例: src/posts/2021-04-18-test2/index.mdx)

---
slug: "test2"
title: "テスト"
images:
    - ./image-01.jpg
    - ./image-02.jpg
    - ./image-03.jpg
---
テストだよ

import SlideShow from '../../components/SlideShow'

<SlideShow images={props.frontmatter.images} interval={1000} autoPlay={true} infiniteLoop={false} />

さらに、index.mdx と同じフォルダに images で指定した画像(この例では image-01.jpg, image-02.jpg, image-03.jpg)を格納します。

※画像ファイルがないと gatsby developgatsby build を実行した際にエラーになるため、必ず事前に画像を格納しておく必要があります。

動作確認

gatsby develop で動作確認できます。

実際の動作イメージはこちらの記事でも確認できます。

コードこちら:

かわかみしんいち。島根県津和野町在住のフリーランスエンジニア。複合現実(Mixed Reality)と3DUXでおもちゃを作るのが趣味。 https://github.com/ototadana