勉強しながら少しずつブログに機能を追加してますが、今回は「次の記事」「前の記事」のリンクを実装していきたいと思います。
先ずはgatsby-node.js
で「次の記事」「前の記事」のデータを取得できるようにします。GraphQlでnextとpreviousを取得します。取得できるデータはhttp://localhost:8000/___graphql
で確認してみてください。
await graphql(`
{
allMarkdownRemark(
sort: { order: DESC, fields: [frontmatter___date] }
){
next {
fields {
slug
}
frontmatter {
title
date
featuredimage {
childImageSharp {
gatsbyImageData (
)
}
}
}
}
previous {
fields {
slug
}
frontmatter {
title
date
featuredimage {
childImageSharp {
gatsbyImageData (
)
}
}
}
}
}
}
}
次にallMarkdownRemarkで取得したデータを各テンプレートsrc/templates/${String(edge.node.frontmatter.templateKey)}
に渡します。
const posts = result.data.allMarkdownRemark.edges
posts.forEach((edge) => {
const id = edge.node.id
createPage({
path: edge.node.fields.slug,
tags: edge.node.frontmatter.tags,
component: path.resolve(
`src/templates/${String(edge.node.frontmatter.templateKey)}.js`
),
context: {
id,
next: edge.next, //追加
previous: edge.previous, //追加
},
データを渡したらデータを受け取りましょう。ブログ記事に「次の記事」「前の記事」を実装したいので、受け取る場所はブログテンプレートです。propsでpageContext
が使えるようになり、contextのデータを受け取ることができます。受け取ったらPrevNextコンポーネントを作っているのでさらにデータを渡します。
export const BlogPostTemplate = ({
//...省略
pageContext,
}) => {
return (
//...省略
<PrevNext pageContext={pageContext} />
);
};
//...省略
const BlogPost = ({ data, pageContext}) => {
const { markdownRemark: post } = data;
const { siteUrl } = useSiteMetadata();
return (
<Layout>
<BlogPostTemplate
//...省略
pageContext={pageContext}
/>
</Layout>
);
};
PrevNextコンポーネントはこんな感じです。スタイリングはここで加えていきます。
import React from "react"
import { Link } from 'gatsby'
import PreviewCompatibleImage from './PreviewCompatibleImage'
const prevNext = ({ pageContext }) => {
const { next, previous } = pageContext;
return (
<div className="columns blog-module--prev-next">
{ previous.frontmatter.date == null || previous == null ? null :
<div className="column is-half">
<h3>次の記事</h3>
<div className="line-height-initial">
<Link to={`${previous.fields.slug}`} className="MuiButtonBase-root">
{previous.frontmatter.featuredimage ? (
<div className="MuiBox-root">
<PreviewCompatibleImage
imageInfo={{
image: previous.frontmatter.featuredimage,
alt: `featured image thumbnail for post ${previous.frontmatter.title}`,
}}
/>
</div>
) : null}
<div className="MuiCardContent-root">
<span className="is-size-small-2">
{previous.frontmatter.title}
</span>
</div>
</Link>
</div>
</div>
}
{ next == null ? null :
<div className="column is-half">
<h3>前の記事</h3>
<div className="line-height-initial">
<Link to={`${next.fields.slug}`} className="MuiButtonBase-root">
{next.frontmatter.featuredimage ? (
<div className="MuiBox-root">
<PreviewCompatibleImage
imageInfo={{
image: next.frontmatter.featuredimage,
alt: `featured image thumbnail for post ${next.frontmatter.title}`,
}}
/>
</div>
) : null}
<div className="MuiCardContent-root">
<span className="is-size-small-2">
{next.frontmatter.title}
</span>
</div>
</Link>
</div>
</div>
}
</div>
)
}
export default prevNext;
スタイリングなど少し雑ですがこれで実装完了です。gatsby-node.jsのデータの渡し方の仕組みなど理解することができて学びが多い実装になりました。参考になれば幸いです。