Gatsbyでページングをいれる

September 12, 2022

これは何?

gatsby-blog-starter を用いて作成したプロジェクトの一覧ページで、ページングを実装する方法です。

確認環境

$ gatsby --version
Gatsby CLI version: 4.4.0
Gatsby version: 4.5.2

gatsby-awesome-pagination をインストールする

$ npm install gatsby-awesome-pagination

トップページをテンプレート化する

$ mv src/pages/index.js src/templates/index.js

gatsby-node.js の修正

git diff の結果を貼っておきます。

gatsby-node.js

+const { paginate } = require("gatsby-awesome-pagination")

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

   // Define a template for blog post
   const blogPost = path.resolve(`./src/templates/blog-post.js`)
+  // Define a template for blog index
+  const blogList = path.resolve(`./src/templates/index.js`)

   // Get all markdown blog posts sorted by date
   const result = await graphql(
@@ -37,6 +40,15 @@ exports.createPages = async ({ graphql, actions, reporter }) => {

   const posts = result.data.allMarkdownRemark.nodes

+  // for paging
+  paginate({
+    createPage,
+    items: posts,
+    itemsPerPage: 10,
+    component: blogList,
+    pathPrefix: ({ pageNumber }) => (pageNumber === 0 ? "/" : "/page"),
+  })

GraphQLの修正 (トップページを生成するテンプレート)

src/templates/index.js

 export const pageQuery = graphql`
-  query {
+  query ($skip: Int!, $limit: Int!) {
     site {
       siteMetadata {
         title
       }
     }
-    allMarkdownRemark(sort: { fields: [frontmatter___date], order: DESC }) {
+    allMarkdownRemark(
+      skip: $skip
+      limit: $limit
+      sort: { fields: [frontmatter___date], order: DESC }
+    ) {

ページングのリンクを表示

src/templates/index.js

-const BlogIndex = ({ data, location }) => {
+const BlogIndex = ({ data, location, pageContext }) => {
   const siteTitle = data.site.siteMetadata?.title || `Title`
   const posts = data.allMarkdownRemark.nodes

@@ -59,6 +59,11 @@ const BlogIndex = ({ data, location }) => {
           )
         })}
       </ol>
+
+      <div>
+        <Link to={pageContext.previousPagePath}>前のページへ</Link>
+        <Link to={pageContext.nextPagePath}>次のページへ</Link>
+      </div>
     </Layout>

下記のような制御を入れるのがいいと思います。

  • 1ページ目では、“前のページへ”を表示しない (リンクを付けない)
  • 最後のページでは、“次のページへ”を表示しない (リンクを付けない)

参考


SHARE

Profile picture

Written by tamesuu