2019-01-22に投稿

GatsbyJSでMarkdownの記事を表示させよう

GatsbyJSでMarkdownの記事を表示させよう

Markdownファイルをそのまま表示させることは出来ません。
そこで、Markdownファイルを表示するページを動的に生成する必要があります。
Gatsbyでそのようなことをする場合はgatsby-node.jsを使います。
やることは2つです。
+ onCreateNode
+ createPage
onCreateNodeでslugを動的に生成します。(xxx.com/my1stpost/のmy1stpostにあたる部分)
そのslugを元にtempleteファイルを作成し、createPageでpageを生成します。

gatsby-node.js

const path = require(`path`)
const { createFilePath } = require(`gatsby-source-filesystem`)

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

  return new Promise((resolve, reject) => {
    const blogPost = path.resolve(`./src/templates/blog-post.js`)
      // graphqlからデータの取得
    resolve(
      graphql(
        `
          {
            allMarkdownRemark(
              sort: { fields: [frontmatter___date], order: DESC }
              limit: 1000
            ) {
              edges {
                node {
                  fields {
                    slug
                  }
                  frontmatter {
                    title
                  }
                }
              }
            }
          }
        `
      ).then(result => {
        if (result.errors) {
          console.log(result.errors)
          reject(result.errors)
        }

        // 投稿ページの生成
        const posts = result.data.allMarkdownRemark.edges

        posts.forEach((post, index) => {
          const previous =
            index === posts.length - 1 ? null : posts[index + 1].node
          const next = index === 0 ? null : posts[index - 1].node

          createPage({
            path: post.node.fields.slug,
            component: blogPost,
            context: {
              slug: post.node.fields.slug,
              previous,
              next,
            },
          })
        })
      })
    )
  })
}
  // slugの生成
exports.onCreateNode = ({ node, actions, getNode }) => {
  const { createNodeField } = actions

  if (node.internal.type === `MarkdownRemark`) {
    const value = createFilePath({ node, getNode })
    createNodeField({
      name: `slug`,
      node,
      value,
    })
  }
}

次にblog-post.jsを作っていきます。

import React from 'react'
import { Link, graphql } from 'gatsby'

import Layout from '../components/Layout'
import SEO from '../components/seo'

class BlogPostTemplate extends React.Component {
  render() {
    const post = this.props.data.markdownRemark
    const siteTitle = this.props.data.site.siteMetadata.title
    const { previous, next } = this.props.pageContext

    return (
      <Layout location={this.props.location} title={siteTitle}>
        <SEO title={post.frontmatter.title} description={post.excerpt} />
        <h1>{post.frontmatter.title}</h1>
        <p>
          {post.frontmatter.date}
        </p>
        <div dangerouslySetInnerHTML={{ __html: post.html }} />
        <hr/>

        <ul>
          <li>
            {previous && (
              <Link to={previous.fields.slug} rel="prev">
                ← {previous.frontmatter.title}
              </Link>
            )}
          </li>
          <li>
            {next && (
              <Link to={next.fields.slug} rel="next">
                {next.frontmatter.title} →
              </Link>
            )}
          </li>
        </ul>
      </Layout>
    )
  }
}

export default BlogPostTemplate

export const pageQuery = graphql`
  query BlogPostBySlug($slug: String!) {
    site {
      siteMetadata {
        title
        author
      }
    }
    markdownRemark(fields: { slug: { eq: $slug } }) {
      id
      excerpt(pruneLength: 160)
      html
      frontmatter {
        title
        date(formatString: "MMMM DD, YYYY")
      }
    }
  }
`

これで準備が出来ました。

確認作業

それでは確認作業をしてみましょう。
gatsby developでサーバーを立ち上げ
http://localhost:8000/aにアクセスしてみましょう。
013.jpg
404と表示されますが上記のようにディレクトリが分かれているのがわかります。ちゃんと/my1stpost/があります。
早速、アクセスしてみましょう!
0131.jpg
ちゃんと表示されていますね!お疲れ様でした。

Originally published at www.corylog.com

view_list [連載] ブロガー向けGatsby講座
第10回 GatsbyJSのgatsby-source-filesystemを使う
第11回 GatsbyJSでMarkdownで記事の一覧を表示させよう
第12回 GatsbyJSでMarkdownの記事を表示させよう
第13回 GatsbyJSでfontawesomeを使う
第14回 GatsbyJSでフォントを変更する

aocory

Crieitは個人で開発中です。 興味がある方は是非記事の投稿をお願いします! どんな軽い内容でも嬉しいです。
なぜCrieitを作ろうと思ったか

また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!

こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください!

ボードとは?

関連記事

コメント