Gatsbyにページネーションを実装する

Gatsbyでページネーションを追加したのでメモ。 ページネーションを追加するプラグインはいくつかあったけど、今回はgatsby-awesome-paginationを使用した。

実装にあたって下記の記事を参考にさせていただきました。有益な記事をありがとうございました。

gatsby-awesome-paginationでGatsbyにpaginationをつけた

1. プラグインのインストール

npm i -S gatsby-awesome-pagination

2. gatsby-node.jsの設定

つづいてgatsby-node.jsにページネーションのビルド設定を追加する。以下該当部分を抜粋。

// プラグインの読み込み
const path = require("path")
const { paginate } = require("gatsby-awesome-pagination")

exports.createPages = ({ actions, graphql }) => {
	const { createPage } = actions

	// ページネーション関数buildPaginationを作成
	const buildPagination = posts => {
		paginate({
			createPage,
			items: posts,
			itemsPerPage: 10,
			// 2ページ目以降はURLに"/page"が付与されるよう設定
			pathPrefix: ({ pageNumber }) => (pageNumber === 0 ? "/" : "/page"),
			component: path.resolve('src/templates/index.js')
		})
	}

	return graphql(`
			{
				allMarkdownRemark(
					sort: { order: DESC, fields: [frontmatter___date] }
					limit: 1000
				) {
					edges {
						node {
							frontmatter {
								path
								tags
							}
						}
					}
				}
			}
		`).then(result => {
			if (result.errors) {
				return Promise.reject(result.errors)
			}
			const posts = result.data.allMarkdownRemark.edges

			// buildPagination関数の実行
			buildPagination(posts)
		})
	})
}

3. ページネーションコンポーネントの作成

次はページネーションのコンポーネントを作成する。

src/components/Pagination.js

import { Link } from "gatsby"
import React from "react"
import styles from "./Pagination.module.css"

const Pagination = ({ props }) => {
	const { pageContext } = props;
	const { previousPagePath, nextPagePath } = pageContext;

	return (
		<div className={styles.pagination}>
			{previousPagePath ? <Link to={previousPagePath}>前のページ</Link> : null }
			{nextPagePath ? <Link to={nextPagePath}>次のページ</Link> : null }
		</div>
	)
}

export default Pagination

4. template/index.jsを修正

あとはPaginationコンポーネントを対象のテンプレートに読み込む。 正直propsという名前が合っていない気がするけど

import React from "react"
import { graphql } from "gatsby"
import Layout from "../components/layout"
import PostLinkItem from "../components/post-link-item"
import Pagination from "../components/Pagination/Pagination"
import SEO from "../components/seo"

const IndexTemplate = props => {
	const Posts = props.data.allMarkdownRemark.edges
		.filter(edge => !!edge.node.frontmatter.date)
		.map(edge => <PostLinkItem key={edge.node.id} post={edge.node} />)

	return (
		<Layout>
			<SEO title="Home" keywords={[`gatsby`, `application`, `react`]} />
			<div>{Posts}</div>
			// Pagination関数の実行
			<Pagination props={props} />
		</Layout>
	)
}

以上で実装が完了した。