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)
ちゃんと表示されていますね!お疲れ様でした。