W.D.Sphere

ウェブ開発の技術を楽しむ空間

Gatsby.js スタティックサイトのチュートリアル Part 8

Gatsby.jsでMDXを使用したブログサイトを作成するチュートリアルのPart8です。今回はgatsby-plugin-imageのGatsbyImageコンポーネントを使用して、各ブログポストにヒーローイメージを追加して、ブログページのリストにも表示できるようにしていきます。

GatsbyImageコンポーネント

このチュートリアルのPart3でホームページに画像を表示した際はStaticImageコンポーネントで画像を表示しましたが、動的ルーティングで作成されたブログポストのページにpropsとしてイメージを受け渡す場合にはGatsbyImageコンポーネントを使用する必要があります。

ブログポストにヒーローイメージを追加する

まずblogディレクトリの構成を変更する必要があります。いまはblogフォルダの直下に各記事のMDXファイルが置かれている状態です。

gatsby-static-site-tutorial8-01.png

これを各ブログポストごとにサブディレクトリを作成し、各MDXファイルをindex.mdxにリネームします。

gatsby-static-site-tutorial8-02
gatsby-static-site-tutorial8-03

なおフォルダ構成を変更した際はローカルサーバーの再起動が必要です。ヒーローイメージに使用する任意の画像を各ブログポストのフォルダに格納します。

gatsby-static-site-tutorial8-04

各ブログポストのfrontmatterにヒーローイメージのpathとaltテキストを追記します。

blog/first-post/index.mdx frontmatter

---
title: "First Post"
date: "2024-04-01"
slug: "first-post"
hero_image: "./sample-image-1.png"
hero_image_alt: "Alt text for your image"
---

blog/second-post/index.mdx frontmatter

---
title: "Second Post"
date: "2024-04-02"
slug: "second-post"
hero_image: "./sample-image-2.png"
hero_image_alt: "Alt text for your image"
---

blog/third-post/index.mdx frontmatter

---
title: "Third Post"
date: "2024-04-03"
slug: "third-post"
hero_image: "./sample-image-3.png"
hero_image_alt: "Alt text for your image"
---

blog/fourth-post/index.mdx frontmatter

---
title: "Fourth Post"
date: "2024-04-04"
slug: "fourth-post"
hero_image: "./sample-image-4.png"
hero_image_alt: "Alt text for your image"
---

blog/fifth-post/index.mdx frontmatter

---
title: "Fifth Post"
date: "2024-04-05"
slug: "fifth-post"
hero_image: "./sample-image-5.png"
hero_image_alt: "Alt text for your image"
---

blog/sixth-post/index.mdx frontmatter

---
title: "Sixth Post"
date: "2024-04-06"
slug: "sixth-post"
hero_image: "./sample-image-6.png"
hero_image_alt: "Alt text for your image"
---

gatsby-transformer-sharpプラグインで画像を変換する

GatsbyImageコンポーネントを使用するためにgatsby-transformer-sharpプラグインをインストールします。このプラグインを使用すると画像ファイル(.pngや.jpgといった拡張子のファイル)をImageSharpノードに変換しGraphQLで取得できるようにしてくれます。CLIで下記コマンドを実行します。

npm install gatsby-transformer-sharp

gatsby-transformer-sharpをgatsby-config.jsに追記します。

gatsby-config.js

module.exports = {
  siteMetadata: {
    title: `Gatsby Static Site Tutorial`,
  },
  plugins: [
    `gatsby-plugin-image`,
    `gatsby-plugin-sharp`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `blog`,
        path: `${__dirname}/blog`,
      }
    },
    `gatsby-plugin-mdx`,
    `gatsby-transformer-sharp`,
  ],
};

gatsby-config.jsを変更したのでローカルサーバーを再起動しておきましょう。

ブログポストにヒーローイメージを表示する

画像と必要なツールが準備できたので{mdx.frontmatter__slug}.jsにGatsbyImageコンポーネントを追加します。まずGraphiQLでクエリを作成します。frontmatterのhero_image_altとhero_image内の childImageSharp → gatsbyImageData を追加で選択すればOKです。

gatsby-static-site-tutorial8-05

クエリは下記のようになります。

GraphQL

query ($id: String) {
  mdx(id: {eq: $id}) {
    frontmatter {
      title
      date(formatString: "MMMM D, YYYY")
      hero_image_alt
      hero_image {
        childImageSharp {
          gatsbyImageData
        }
      }
    }
  }
}

クエリを作成できたので{mdx.frontmatter__slug}.jsを下記のように変更します。

src/pages/blog/{mdx.frontmatter__slug}.js

import * as React from 'react'
import { graphql } from 'gatsby'
import { GatsbyImage, getImage } from 'gatsby-plugin-image'
import Layout from '../../components/layout'
import Seo from '../../components/seo'

const BlogPost = ({ data, children }) => {
  const image = getImage(data.mdx.frontmatter.hero_image)
  return (
    <Layout pageTitle={data.mdx.frontmatter.title}>
      <p>{data.mdx.frontmatter.date}</p>
      <GatsbyImage
	image={image}
	alt={data.mdx.frontmatter.hero_image_alt}
      />
      {children}
    </Layout>
  )
}

export const query = graphql`
  query ($id: String) {
    mdx(id: {eq: $id}) {
      frontmatter {
	title
	date(formatString: "MMMM D, YYYY")
	hero_image_alt
	hero_image {
          childImageSharp {
            gatsbyImageData
          }
	}
      }
    }
  }
`

export const Head = ({ data }) => <Seo title={data.mdx.frontmatter.title} />

export default BlogPost

gatsby-plugin-imageプラグインからGatsbyImageとgetImageを読み込みます。getImageはGatsbyImageから画像を取得する際に使用するヘルパーファンクションです。これで各ブログポストのページにヒーローイメージが追加できました。

gatsby-static-site-tutorial8-06

ブログページにブログポストのヒーローイメージを表示する

ブログの一覧ページでも画像を表示できるようにします。GraphiQLで下記のようにクエリを作成します。

gatsby-static-site-tutorial8-07

GraphQL

query MyQuery {
  allMdx(sort: {frontmatter: {date: DESC}}) {
    nodes {
      frontmatter {
        title
        date(formatString: "MMMM D, YYYY")
        slug
        hero_image_alt
        hero_image {
          childImageSharp {
            gatsbyImageData
          }
        }
      }
      id
      excerpt
    }
  }
}

hero_imageとhero_image_altを追加しています。ブログページを下記のように変更します。

src/pages/blog/index.js

import * as React from 'react'
import { Link, graphql } from 'gatsby'
import { GatsbyImage, getImage } from 'gatsby-plugin-image'
import Layout from '../../components/layout'
import Seo from '../../components/seo'

const BlogPage = ({ data }) => {
  return (
    <Layout pageTitle="Blog">
      {
        data.allMdx.nodes.map((node) => (
          <article key={node.id}>
	    <h2>
	      <Link to={`/blog/${node.frontmatter.slug}`}>
		{node.frontmatter.title}
              </Link>
	    </h2>
	    <GatsbyImage
	      image={getImage(node.frontmatter.hero_image)}
	      alt={node.frontmatter.hero_image_alt}
	    />
            <p>Posted: {node.frontmatter.date}</p>
            <p>{node.excerpt}</p>
          </article>
        ))
      }
    </Layout>
  )
}

export const query = graphql`
  query {
    allMdx(sort: { frontmatter: { date: DESC }}) {
      nodes {
        frontmatter {
          title
          date(formatString: "MMMM D, YYYY")
	  slug
	  hero_image_alt
          hero_image {
            childImageSharp {
              gatsbyImageData
            }
          }
        }
        id
        excerpt
      }
    }
  }
`

export const Head = () => <Seo title="Blog" />

export default BlogPage

GatsbyImageとgetImageを読み込み、クエリを置きかえます。タイトルの下に画像を表示するようにしています。

gatsby-static-site-tutorial8-08

これでブログの一覧ページにもヒーローイメージを追加できました。今回は以上です。


< Previous ArticleNext Article >
Back to Articles
©2025 W.D.Sphere All Rights Reserved.