GatsbyでMDX形式の記事を扱えるようにするための手順メモです。

今回は gatsby-plugin-mdx が組み込まれた starter は使いません。 クリーンな状態から初めて最低限の記述で動作させることを目指します。

1.プロジェクト作成

最初に gatsby-starter-hello-world を使って新規プロジェクト作成します。

gatsby new mdx-example https://github.com/gatsbyjs/gatsby-starter-hello-world
cd mdx-example

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

gatsby-plugin-mdx を実行するために必要なプラグインをインストールします。

npm install gatsby-plugin-mdx @mdx-js/mdx @mdx-js/react gatsby-source-filesystem

gatsby-config.js に gatsby-plugin-mdx と gatsby-source-filesystem のプラグイン設定を行います。

module.exports = {
  plugins: [
    `gatsby-plugin-mdx`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        path: `src/posts`,
        name: `posts`
      }
    },
  ],
}
  • gatsby-plugin-mdx に関しては、とりあえずオプションなしにしてます。 オプション等の詳細は gatsby-plugin-mdx のドキュメント を参照してください。
  • gatsby-source-filesystem の path で指定した src/posts は mdx ファイルの格納場所です。

3.gatsby-node.jsの作成

トップディレクトリに gatsby-node.js を作成し、createPages ファンクションを記述します。

今回は「src/templates/blog-post.js ファイルをひな型として記事を作成する」という形にしています。

const path = require("path")

exports.createPages = async ({ actions, graphql, reporter }) => {
  const { createPage } = actions

  const blogPostTemplate = path.resolve(`src/templates/blog-post.js`)

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

  if (result.errors) {
    reporter.panicOnBuild(`Error while running GraphQL query.`)
    return
  }

  result.data.allMdx.edges.forEach(({ node }) => {
    createPage({
      path: node.frontmatter.slug,
      component: blogPostTemplate,
      context: {
        slug: node.frontmatter.slug,
      }
    })
  })
}

4.src/templates/blog-post.jsの作成

記事のひな型となる src/templates/blog-post.js ファイルを作成します。

import React from "react"
import { graphql } from "gatsby"
import MDXRenderer from "gatsby-plugin-mdx/mdx-renderer"

const Blog = ({ data }) => (
  <>
    <h1>{data.mdx.frontmatter.title}</h1>
    <hr/>
    <MDXRenderer frontmatter={data.mdx.frontmatter}>{data.mdx.body}</MDXRenderer>
  </>
)
export default Blog

export const pageQuery = graphql`
  query BlogPostBySlug($slug: String!) {
    mdx(frontmatter: { slug: { eq: $slug } }) {
      body
      frontmatter {
        title
        slug
      }
    }
  }
`

4.記事をMDXで書く

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

---
slug: "test1"
title: "テスト"
---
テストだよ

* <div>1+1={1+1}</div>
* <div>slug: {props.frontmatter.slug}</div>
* <div>title: {props.frontmatter.title}</div>

5.動作確認

起動します。

gatsby develop

起動できたら、ブラウザで http://localhost:8000/[slug] (例: http://localhost:8000/test1)にアクセスします。

動作確認

無事表示できました。

コード全体は GitHub にアップしました:

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