Et si on paginait notre page d'accueil avec Gatsby et Getsby Paginate ?

Après avoir longuement bataillé avec mes slugs, je me suis attaqué à un autre élément important quand on veut développer un joli blog : la pagination !

J'ai défait et refait mon code un nombre incalculable de fois avant de parvenir à un résultat "satisfaisant". Je mets ce mot entre guillemets car je pense qu'il y a bien plus court que mon pâté, mais c'est quand même un début de piste si vous souhaitez vous aussi mettre ça en place ;)

On commence par installer Gatsby-paginate :

npm install gatsby-paginate

On configure ensuite notre création de pages dans le fichier gatsby-node.js :

exports.createPages = async ({ graphql, actions }) => {
  const createPaginatedPages = require("gatsby-paginate")
  const { createPage } = actions
  const result = await graphql(
    `
      {
        articles: allStrapiArticle(sort: { fields: updated_at, order: DESC }) {
          edges {
            node {
              strapiId
              title
              content
              updated_at
              image {
                publicURL
              }
              categories {
                name
                id
                slug
              }
              tags {
                name
                id
                slug
              }
              slug
            }
          }
        }

        categories: allStrapiCategory {
          edges {
            node {
              strapiId
              slug
            }
          }
        }
        tags: allStrapiTag {
          edges {
            node {
              strapiId
              slug
            }
          }
        }
      }
    `
  )

  if (result.errors) {
    throw result.errors
  }

  // Create blog articles pages.
  const articles = result.data.articles.edges
  const categories = result.data.categories.edges
  const tags = result.data.tags.edges

  articles.forEach((article, index) => {
    createPage({
      path: `/article/${article.node.slug}`,
      component: require.resolve("./src/templates/article.js"),
      context: {
        slug: article.node.slug,
        title: article.node.title,
      },
    })
  })

  categories.forEach((category, index) => {
    createPage({
      path: `/category/${category.node.slug}`,
      component: require.resolve("./src/templates/category.js"),
      context: {
        slug: category.node.slug,
      },
    })
  })

  tags.forEach((tag, index) => {
    createPage({
      path: `/tag/${tag.node.slug}`,
      component: require.resolve("./src/templates/tag.js"),
      context: {
        slug: tag.node.slug,
      },
    })
  })

  createPaginatedPages({
    edges: result.data.articles.edges,
    createPage: createPage,
    pageTemplate: "src/templates/index.js",
    pageLength: 6, // This is optional and defaults to 10 if not used
    pathPrefix: "", // This is optional and defaults to an empty string if not used
    context: {}, // This is optional and defaults to an empty object if not used
  })
  
}

On supprime ensuite le fichier pages/index.js et on vient créer un templates/index.js :

import React from "react"

import Layout from "../components/layout"
import ArticlesComponent from "../components/Articles"
import PaginationNav from "../components/PaginationNav"

import "../../Custom.scss"

const IndexPage = ({ pageContext }) => {
  const { group, index, pageCount, pathPrefix } = pageContext

  const paginationContext = {
    currentPage: index,
    numPages: pageCount,
    pathPrefix: pathPrefix,
  }

  return (
    <Layout>
      <ArticlesComponent articles={group} key={`${group.length}_articles`} />
      <PaginationNav pageContext={paginationContext} />
    </Layout>
  )
}
export default IndexPage

Enfin on crée le components/PaginationNav.js (et là vous m'excuserez je l'espère pour la longueur du code :P) :

import React from "react"
import { Link } from "gatsby"
import { Button } from "react-bootstrap"

const PaginationNav = props => {
  const pageActu = props.pageContext.currentPage
  const numPages = props.pageContext.numPages
  const pathName = props.pageContext.pathPrefix

  return (
    <>
      {numPages !== 1 ? (
        <nav className="pagination">
          {pageActu === 1 ? (
            <>
              <Button className="isActu"> 1 </Button>
              <Link to={`${pathName}/2`}>
                <Button> 2 </Button>
              </Link>
              {numPages > 2 ? (
                <Link to={`${pathName}/3`}>
                  <Button> 3 </Button>
                </Link>
              ) : (
                ""
              )}
              {numPages > 3 ? (
                <Link to={`${pathName}/4`}>
                  <Button> 4 </Button>
                </Link>
              ) : (
                ""
              )}
              {numPages > 4 ? (
                <>
                  <span> ... </span>
                  <Link to={`${pathName}/${numPages}`}>
                    <Button> {numPages} </Button>
                  </Link>
                </>
              ) : (
                ""
              )}
            </>
          ) : (
            <>
              <Link to={`${pathName}/`}>
                <Button>1</Button>
              </Link>

              {pageActu > 3 ? (
                <>
                  <span> ... </span>
                  <Link to={`${pathName}/${pageActu - 1}`}>
                    <Button> {pageActu - 1} </Button>
                  </Link>
                </>
              ) : (
                <>
                  {pageActu !== 2 ? (
                    <Link to={`${pathName}/${pageActu - 1}`}>
                      <Button> {pageActu - 1} </Button>
                    </Link>
                  ) : (
                    ""
                  )}
                </>
              )}

              <Button className="isActu"> {pageActu} </Button>

              {pageActu <= numPages - 2 ? (
                <>
                  <Link to={`${pathName}/${pageActu + 1}`}>
                    <Button> {pageActu + 1} </Button>
                  </Link>

                  {pageActu === numPages - 2 ? (
                    <>
                      <Link to={`${pathName}/${numPages}`}>
                        <Button> {numPages} </Button>
                      </Link>
                    </>
                  ) : (
                    <>
                      <span> ... </span>
                      <Link to={`${pathName}/${numPages}`}>
                        <Button> {numPages} </Button>
                      </Link>
                    </>
                  )}
                </>
              ) : (
                <>
                  {pageActu <= numPages - 1 ? (
                    <Link to={`${pathName}/${numPages}`}>
                      <Button> {numPages} </Button>
                    </Link>
                  ) : (
                    ""
                  )}
                </>
              )}
            </>
          )}
        </nav>
      ) : (
        ""
      )}
    </>
  )
}

export default PaginationNav

Voilà, votre page d'accueil est désormais plus légère ! A bientôt pour la pagination des articles par catégorie et par tag, et d'ici là, codez-bien ;)