© 2020 Addapter Inc.

BLOG

GatsbyJSで最速でブログを作る!

コーディング2021/03/30
アバター
なーこ

今日は、GatsbyJSを使ってブログを作っていこうと思います!

GatsbyJSの紹介

まずは簡単にGatsbyJSの紹介をしていきます。

GatsbyJSとはReactを用いて手軽にサイトを構築できるフレームワークです。

使用用途としては、ブログ、ECサイト、LPなどが挙げられます。

今回は、GatsbyJSを用いて、簡単なブログを作成していきます!

つくるもの

ブログの超基本的なページを作っていきます。

具体的には以下の二つのページです。

  • ブログ一覧ページ
  • 記事ページ

まずはブログ一覧ページを作っていきましょう!

ブログ一覧ページ

今回の基礎となるコードを入手します。

git clone [email protected]:NearCloser/gatsby-blog-tutorial.git

そして以下の二つのプラグインをインストールします。

yarn add  gatsby-source-filesystem   gatsby-transformer-remark

gatsby-source-filesystemはファイルをgatsbyに取り込むプラグインで、gatsby-transformer-remarkはマークダウン形式のファイルをhtmlに変換するプラグインです。

gatsby-config.jsにこれらのプラグインを追記していきます。

module.exports = {
  /* Your site config here */
  plugins: [
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `content`,
        path: `${__dirname}/content/`,
      },
    },
    "gatsby-transformer-remark",
  ],
}

プラグインのオプションのパスに入っているファイルがGatsbyJsに読み込まれるようになります。

ここで以下のコマンドで開発用サーバーを起動してみましょう。

yarn dev

以下のurlにアクセスします。

http://localhost:8000/___graphql

ここはGraphQLを確認できる場所です。

以下のコードを左のエディタに記入して、真ん中の実行ボタンを押してみましょう。

query {
      allMarkdownRemark(sort: { fields: frontmatter___date, order: DESC }) {
        edges {
          node {
            frontmatter {
              title
              date
            }
            excerpt(truncate: true, pruneLength: 100)
            timeToRead
          }
        }
      }
    }

すると、以下のデータが現れてきます!

{
  "data": {
    "allMarkdownRemark": {
      "edges": [
        {
          "node": {
            "frontmatter": {
              "title": "サード",
              "date": "2021-03-28"
            },
            "excerpt": "サードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサードサード…"
          }
        },
        {
          "node": {
            "frontmatter": {
              "title": "セカンド",
              "date": "2021-03-24"
            },
            "excerpt": "セカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカンドセカン…"
          }
        },
        {
          "node": {
            "frontmatter": {
              "title": "イントロダクション",
              "date": "2021-03-20"
            },
            "excerpt": "イントロダクションイントロダクションイントロダクションイントロダクションイントロダクションイントロダクションイントロダクションイントロダクションイントロダクションイントロダクションイントロダクション…"
          }
        }
      ]
    }
  },
  "extensions": {}
}

このデータを用いてブログリストを作っていきます。

GatsbyJSにはuseStaticQueryというメソッドが用意されており、これを使うことで簡単にGraphQLのデータを引き出すことができます。

ここではdataという定数にデータをいれています。

  const data = useStaticQuery(graphql`
    query {
      allMarkdownRemark(sort: { fields: frontmatter___date, order: DESC }) {
        edges {
          node {
            frontmatter {
              title
              date
            }
            excerpt(truncate: true, pruneLength: 100)
            timeToRead
          }
        }
      }
    }
  `)

JSXには以下のようにdataをmapメソッドで展開し、リストを作成します。

    <div>
      <h1>ブログリスト</h1>
      <ul>
        {data.allMarkdownRemark.edges.map(({ node }) => {
          return (
            <li key={node.frontmatter.title}>
              <h2>{node.frontmatter.title}</h2>
              <p>{node.frontmatter.date}</p>
            </li>
          )
        })}
      </ul>
    </div>

最終的には以下のようなブログ一覧ページができあがります。

記事ページ

次に記事ページを作っていきます!

slugとは、個々の記事を区別する ID です.

ここではわかりやすく、 slug = filename (記事のファイル名) と設定します.

gatsby-node.jsに以下のコードを足します。

const path = require('path')

module.exports.onCreateNode = ({ node , actions }) => {
    const { createNodeField } = actions
    if (node.internal.type === 'MarkdownRemark') {
        const slug = path.basename(node.fileAbsolutePath , '.md' )

        createNodeField({
            node,
            name: 'slug',
            value: slug
        })

    }

}

onCreateNodeというメソッドを使って、マークダウンファイルのファイル名をslugという名前で登録します。

こうすることで、GraphQL上でスラグを取得することが可能となります。

ここでは、 templates フォルダを作り、そこに記事の テンプレートを作成し、さきほど作った slug と 記事のデータ を対応付けることによって、テンプレートを一つ作るだけで記事を並べることができます。

 templates フォルダのblog-template.jsには以下のクエリを書きます。

         query {
            allMarkdownRemark {
                edges {
                    node {
                        frontmatter {
                            title
                            date (formatString: "MMMM DD, YYYY")
                        }
                        excerpt
                        fields{
                            slug
                        }
                    }
                }
            }
        }

これは、slugには各記事のファイル名が入り、その名前と等しい(eq = equal)クエリが抽出されるというものになります。

blog-template.jsは以下のような感じになります。

動的ページではuseStaticQueryは使えないので、graphqlメソッドを使用して、クエリを書きます。

データはpropsに入るので、あとはそれを用いて記述するだけです。

export const query = graphql`
    query ( $slug: String! ) {
      markdownRemark (fields: { slug: { eq: $slug } }) {
        frontmatter {
            title
            date(formatString: "MMMM DD, YYYY")
        }
        html
        query {
            allMarkdownRemark {
                edges {
                    node {
                        frontmatter {
                            title
                            date (formatString: "MMMM DD, YYYY")
                        }
                        excerpt
                        fields{
                            slug
                        }
                    }
                }
            }
        }
`

const Blog = (props) => {
    return (
        <div>
            <h1>{props.data.markdownRemark.frontmatter.title}</h1>
            <p>{props.data.markdownRemark.frontmatter.date}</p>
            <div dangerouslySetInnerHTML={{ __html: props.data.markdownRemark.html}}></div>
        </div>
    )
}

export default Blog

最後にslugに対応するページを作成します。

gatsby-node.jsにて以下のコードを書いてみます。

module.exports.createPages = async ({ graphql , actions }) => {
    const { createPage } = actions
    const blogTemplate = path.resolve('./src/templates/blog-template.js')

    const res = await graphql(`
        query {
            allMarkdownRemark {
                edges {
                    node {
                        fields {
                            slug
                        }
                    }
                }
            }
        }
    `)

    res.data.allMarkdownRemark.edges.forEach( ({ node }) => {
        createPage({
            component: blogTemplate ,
            path: `/bloglist/${node.fields.slug}` ,
            context: {
                slug: node.fields.slug
            }
        })
    })

}

クエリのデータを res に格納し、各記事ごとに createpage 関数でページを生成しています。

スラグとページの対応付けはpathにて柔軟に指定することが可能です。

記事ページができたので、さっそく記事一覧ページから記事をみてましょう。

記事一覧ページにて、Linkを追加します。

                        <Link to={`/bloglist/${node.fields.slug}`} >
                            <h2>{node.frontmatter.title}</h2>
                            <p>{node.frontmatter.date}</p>
                        </Link>

LinkコンポーネントもGatsbyJsから提供されています。

これで記事一覧ページから記事ページへと遷移することができました!

以上が基本的なGatsbyJsで作るブログの基本的な形となります。

ほかにもカテゴリー分類や、MDX、検索機能、SEOなどなどさまざまな機能を追加していくことができるので、これからも学習するのが楽しみです。

ここまで読んでくださってありがとうございました。