学習内容
- Contentfulを使ってブログ詳細の情報を更新する
1.gatsby-node.jsのSlugの生成を削除
gatsby-node.js
//slugの生成
module.exports.onCreateNode = ({ node, actions }) => {
const { createNodeField } = actions
//MarkdownRemarkの場合に、slugを追加する
if(node.internal.type === 'MarkdownRemark') {
//basename関数を用いてslugを抽出
const slug = path.basename(node.fileAbsolutePath, '.md')
//nodeの再編成
createNodeField({
node,
name: 'slug',
value: slug
})
}
}
2.Slugのqueryを書き換える(Contentfulから取得)
gatsby-node.js
const path = require('path');
//ページの生成
module.exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
//ブログ詳細ページ用のテンプレートの取得
const blogTemplate = path.resolve('./src/templates/blogDetail.js')
//slugの取得
const res = await graphql(`
query {
allContentfulBlogPost {
edges {
node {
slug
}
}
}
}
`)
//各ページの生成
res.data.allContentfulBlogPost.edges.forEach((edge) => {
createPage({
component: blogTemplate,
path: `/blog/${edge.node.slug}`,
context: {
slug: edge.node.slug
}
})
})
}
3.blogDetail.jsを書き換える
- bodyのjsonをReactコンポーネントに変換してくれるプラグイン
yarn add @contentful/rich-text-react-renderer
- リッチテキストに画像を追加する場合に必要なプラグイン
yarn add @contentful/rich-text-types
src/templates/blogDetail.js
import React from 'react'
import {graphql} from 'gatsby'
import Layout from '../components/layout'
import { Container, Button } from 'react-bootstrap'
// bodyのjsonをReactコンポーネントに変換
import { documentToReactComponents } from '@contentful/rich-text-react-renderer'
export const query = graphql`
query($slug: String!) {
contentfulBlogPost(slug: {eq: $slug}) {
title
createdDate
body {
json
}
}
}
`
function BlogDetail(props) {
// リッチテキストに画像を追加する場合オプションを渡す
// nodeTypeを指定することで、nodeTypeごとに処理を加えることができる
const options = {
renderNode: {
"embedded-asset-block": (node) => {
return (<img
width="100%"
src={node.data.target.fields.file['en-US'].url}
alt={node.data.target.fields.title['en-US']} />)
}
}
}
return (
<Layout>
<Container style={{maxWidth:640}} className="pt-4">
<h1>{props.data.contentfulBlogPost.title}</h1>
<p>{props.data.contentfulBlogPost.createDate}</p>
{documentToReactComponents(props.data.contentfulBlogPost.body.json, options)}
</Container>
<Container className="text-center">
<Button href="/" variant="outline-info">一覧へ戻る</Button>
</Container>
</Layout>
)
}
export default BlogDetail