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

01 21, 2019

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 = graphqlquery 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`にアクセスしてみましょう。
![gatsby](013.jpg)
404と表示されますが上記のようにディレクトリが分かれているのがわかります。ちゃんと/my1stpost/があります。
早速、アクセスしてみましょう!
![gatsby](0131.jpg)
ちゃんと表示されていますね!お疲れ様でした。

コリ

コリといいます。奈良県でサラリーマンをしています。GatsbyJSでサイトを作るのが趣味です。