npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

gatsby-paginate

v1.1.1

Published

This is a small library for paginating an array of posts within gatsby js

Downloads

2,166

Readme

Gatsby-paginate

This library provides a simple API for paginating an array of posts/pages for your blog/site homepage in Gatsby js.

LOOKING FOR MAINTAINERS - please email [email protected] with subject GATSBY_PAGINATE

Installation

yarn add gatsby-paginate

Usage

  • Require the package in your gatsby-node.js file.
  • Add a call to createPaginatedPages in gatsby-node.js.

Then add the following to the top of your gatsby-node.js file.

const createPaginatedPages = require('gatsby-paginate')

Use case 1 - paginate list of posts on home page

To create a paginated index of your blog posts, you need to do four things:

  • Remove the index.js file from the pages directory.
  • Create an index.js file in the templates directory and refer to it in the createPaginatedPages call

Call createPaginatedPages

You probably already have something like this in your gatsby-node.js file to generate the pages for your blog:

exports.createPages = ({ graphql, actions: { createPage } }) => {
  return new Promise((resolve, reject) => {
    graphql(`
      {
        posts: allMarkdownRemark(
          sort: { fields: [frontmatter___date], order: DESC }
        ) {
          edges {
            node {
              id
              frontmatter {
                title
              }
              fields {
                slug
              }
            }
          }
        }
      }
    `).then(result => {
      result.data.posts.edges.map(({ node }) => {
        createPage({
          path: node.fields.slug,
          component: path.resolve('./src/templates/post.js'),
          context: {
            slug: node.fields.slug,
          },
        })
      })
      resolve()
    })
  })
}

Just insert a call to createPaginatedPages before (or after) the createPage function:

exports.createPages = ({ graphql, actions: { createPage } }) => {
  return new Promise((resolve, reject) => {
    graphql(`
      //graphql query
    `).then(result => {
      createPaginatedPages({
        edges: result.data.posts.edges,
        createPage: createPage,
        pageTemplate: 'src/templates/index.js',
        pageLength: 5, // 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
      })
      result.data.posts.edges.map(({ node }) => {
        createPage({
          path: node.fields.slug,
          component: path.resolve('./src/templates/post.js'),
          context: {
            slug: node.fields.slug,
          },
        })
      })
      resolve()
    })
  })
}

Notice that createPaginatedPages is being passed an options object.

  1. edges is the array of nodes that comes from the GraphQL query.
  2. createPage is simply the createPage function you get from actions.
  3. pageTemplate is a template to use for the index page. And
  4. pageLength is an optional parameter that defines how many posts to show per index page. It defaults to 10.
  5. pathPrefix is an optional parameter for passing the name of a path to add to the path generated in the createPagefunc. This is used in use case 2 below.
  6. context is an optional parameter which is used as the context property when createPage is called.

createPaginatedPages will then call createPage to create an index page for each of the groups of pages. The content that describes the blogs (title, slug, etc) that will go in each page will be passed to the template through props.pageContext so you need to make sure that everything that you want on the index page regarding the blogs should be requested in the GraphQL query in gatsby-node.js.

Use case 2 - paginate a post or use pagination on a page other than index

Call createPaginatedPages in the same way as above but...

This time pass in a pathPrefix

createPaginatedPages({
  edges: result.data.posts.edges,
  createPage: createPage,
  pageTemplate: 'src/templates/your_cool_template.js',
  pageLength: 5,
  pathPrefix: 'your_page_name',
  buildPath: (index, pathPrefix) =>
    index > 1 ? `${pathPrefix}/${index}` : `/${pathPrefix}`, // This is optional and this is the default
})

Then...

  • Create a template in tha same way as above but this time
  • Add a pathPrefix
  • (optional) add buildPath if you want to have more control over the pagination URL structure

In this instance a new set of pages will be created at the following path your_site/your_page_name Then a second paginated page of your_site/your_page_name/2

PLEASE NOTE: THE PATH PREFIX FUNCTIONALITY IS UNDER DEVELOPMENT AND MORE FLEXIBILITY WILL BE ADDED SOON

Create the template

This is a simple template which might be used in use case 1 above to replace the index of a blog with a paginated list of posts.

The pageContext object which contains the following 5 keys is passed to the template;

  1. group - (arr) an array containing the number of edges/nodes specified in the pageLength option.
  2. index - (int) this is the index of the edge/node.
  3. first - (bool) Soon to be deprecated - please calculate first using index and pageCount - is this the first page?
  4. last - (bool) Soon to be deprecated - please calculate last using index and pageCount - is this the last page?
  5. pageCount - (int) the total number of pages being paginated through
  6. additionalContext - (obj) optional additional context
import React, { Component } from 'react'
import Link from 'gatsby-link'

const NavLink = props => {
  if (!props.test) {
    return <Link to={props.url}>{props.text}</Link>
  } else {
    return <span>{props.text}</span>
  }
}

const IndexPage = ({ pageContext }) => {
  const { group, index, first, last, pageCount } = pageContext
  const previousUrl = index - 1 == 1 ? '/' : (index - 1).toString()
  const nextUrl = (index + 1).toString()

  return (
    <div>
      <h4>{pageCount} Pages</h4>

      {group.map(({ node }) => (
        <div key={node.id} className="blogListing">
          <div className="date">{node.frontmatter.date}</div>
          <Link className="blogUrl" to={node.fields.slug}>
            {node.frontmatter.title}
          </Link>
          <div>{node.excerpt}</div>
        </div>
      ))}
      <div className="previousLink">
        <NavLink test={first} url={previousUrl} text="Go to Previous Page" />
      </div>
      <div className="nextLink">
        <NavLink test={last} url={nextUrl} text="Go to Next Page" />
      </div>
    </div>
  )
}
export default IndexPage