2020年の5月に、このブログをGatsbyJS + Contentful + Netlifyという構成に移行しました。移行しながら気づいた点、苦戦した点をすこしずつ纏めて行きたいと思います。今回は、GatsbyJS + Contentfulで、ブログ記事のページネーションを実装する方法について書いてみます。
Gatsbyでページネーションを実現するためのプラグインに、gatsby-awesome-paginationがあります。今回はこれを使いました。
npm install --save gatsby-awesome-pagination
でインストールします。
GatbyJSが提供するGatsby Node APIとgatsby-awesome-paginationプラグインとを使って、ページ生成時にページネーション機能を持ったページを生成するよう、gatsby-node.js
を実装します。
だいたい、次のようなコードになりました。
const path = require("path")
const { paginate } = require("gatsby-awesome-pagination")
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
// Contentfulから記事を公開日時降順で取得する
const result = await graphql(`
{
allContentfulPost(sort: { fields: [publishedAt], order: DESC }) {
edges {
node {
// 取得したいフィールドを列挙
}
}
}
}
`)
const posts = result.data.allContentfulPost.edges
// 記事リストページ生成
const template = path.resolve(`src/templates/index.js`)
paginate({
createPage,
items: posts,
component: template,
pathPrefix: ({ pageNumber } => (pageNumber === 0 ? "/", "/pages"),
})
}
上のコードでは、gatsby-awesome-paginationのpaginate
関数を使用して、ページネーション機能のあるページを生成しています。この関数にはcomponent
として、ページのテンプレートを指定する必要があり、それをsrc/templates/index.js
として実装しました。
paginate
関数にcomponentとして指定するテンプレートは、
の2つが必要になります。(前者に気づかず苦戦しました...)
だいたい、次のような実装をしました。
// importやら、styled-componentsの定義は省略しています。
export const pageQuery = graphql`
query($skip: Int!, $limit: Int!) {
allContentfulPost(
sort: { fields: [publishedAt], order: DESC }
skip: $skip
limit: $limit
) {
edges {
node {
// 必要なフィールドを列挙
}
}
}
}
`
const IndexPage = ({ data, pageContext }) => {
const posts = data.allContentfulPost.edges
const Posts = posts.map(({ node }) => (
<Post
key={node.title}
title={node.title}
// ... 必要なPropertyを渡す
/>
))
return (
<Layout>
<Container>
{Posts}
<Pager pageContext={pageContext} />
</Container>
</Layout>
)
}
export default IndexPage
上記のコードのPost
は、記事一覧での記事を表現するコンポーネント、Pager
はページング用のコンポーネントです。Pager
コンポーネントに渡しているpageContext
には、
といった、ページングに必要な値が含まれているので、これらを使ってページング用のコンポーネントを実装しました。
GatsbyJS + Contentfulでページネーションを実現する方法について書いてみました。まとめると、
という流れになりました。最後のページQueryがわかりにくい点でしょうか。