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 IndexPageEnfin 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 ;)