pixelstew / gatsby-paginate

A simple library for paginating posts in Gatsby js.
GNU General Public License v3.0
123 stars 26 forks source link

Application crashes when refreshing from first page of pagination #42

Closed ArthurHwang closed 5 years ago

ArthurHwang commented 5 years ago

My gatsby-node.js:

require("dotenv").config({
  path: `.env.${process.env.NODE_ENV}`
})
const path = require("path")
const createPaginatedPages = require("gatsby-paginate")

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

  return new Promise((resolve, reject) => {
    graphql(
      `
        {
          allWordpressPost(limit: ${process.env.BLOG_LIMIT}) {
            edges {
              node {
                id
                slug
                title
                content
                excerpt
                date
                modified
                categories {
                  name
                }
                author {
                  name
                }
                featured_media {
                  localFile {
                    childImageSharp {
                      fluid {
                        src
                        srcSet
                        base64
                        sizes
                        aspectRatio
                      }
                    }
                  }
                }
              }
            }
          }
        }
      `
    ).then(result => {
      if (result.errors) {
        console.log(result.errors)
        reject(result.errors)
      }

      createPaginatedPages({
        edges: result.data.allWordpressPost.edges,
        createPage: createPage,
        pageTemplate: "./src/components/elements/blog/PostsTemplate.tsx",
        pageLength: 5,
        pathPrefix: "/blog"
      })

      result.data.allWordpressPost.edges.forEach(({ node }) => {
        createPage({
          path: "blog/" + node.slug,
          component: path.resolve(
            "./src/components/elements/blog/PostTemplate.tsx"
          ),
          context: {
            slug: node.slug,
            imageSharp: node.featured_media,
            title: node.title,
            author: node.author.name,
            categories: node.categories,
            modified: node.modified,
            content: node.content
          }
        })
      })
      resolve()
    })
  })
}

Template:

import { Link } from "gatsby"
import React from "react"
import { FaArrowAltCircleLeft, FaArrowAltCircleRight } from "react-icons/fa"
import styled from "styled-components"
import Layout from "../../layouts/Layout"
import BlogCard from "./BlogCard"

interface Props {
  data: {
    allWordpressPost: {
      edges: {
        node: Node
      }
    }
  }
}

interface Node {
  node: {
    id: string
    slug: string
    title: string
    content: string
    excerpt: string
    date: string
    modified: string
  }
}

const NavLink = props => {
  if (!props.test) {
    return <Link to={props.url}>{props.text}</Link>
  } else {
    return <span style={{ textDecoration: "line-through" }}>{props.text}</span>
  }
}

export default function BlogIndex({ data, pathContext }: Props) {
  const { group, index, first, last, pageCount } = pathContext
  const previousUrl = index - 1 === 1 ? "" : (index - 1).toString()
  const nextUrl = (index + 1).toString()

  return (
    <Layout sidebar={true}>
      <BlogPostsWrapper>
        <ul style={{ margin: "0", listStyleType: "none" }}>
          {group.map(({ node }: Node) => (
            <li key={node.id}>
              <Link className="card-wrapper" to={"blog/" + node.slug}>
                <BlogCard data={node} />
              </Link>
            </li>
          ))}
        </ul>
      </BlogPostsWrapper>
      <StyledPagination>
        <div className="previous-link">
          <FaArrowAltCircleLeft className="arrow-left" />
          <NavLink test={first} url={`blog/${previousUrl}`} text="Previous" />
        </div>
        <div className="next-link">
          <NavLink test={last} url={`blog/${nextUrl}`} text="Next" />
          <FaArrowAltCircleRight className="arrow-right" />
        </div>
      </StyledPagination>
    </Layout>
  )
}

const BlogPostsWrapper = styled.section`
  width: 100%;
  margin-bottom: 2rem;
`
const StyledPagination = styled.div`
  display: flex;
  justify-content: space-between;
  margin-bottom: 2rem;
  align-items: center;

  .previous-link,
  .next-link {
    display: flex;
    align-items: center;
  }
  .arrow-left,
  .arrow-right {
    font-size: 2rem;
    margin: 0.5rem;
  }
`

Everything works fine UNLESS refreshing from the first page of pages created by gatsby-paginate

What happens is when a user refreshes from the first page of created paginated pages, this plugin for example goes to URL: /blog instead of https://www.website.com/blog. If a user refreshes from the 2nd page, it works fine.

Any help would be greatly appreciated.

Akurganow commented 5 years ago

Have the same problem and I think problem at this line https://github.com/pixelstew/gatsby-paginate/blob/master/src/index.js#L15

Akurganow commented 5 years ago

My temporary solution:

function buildPath(index, pathPrefix) {
  return index > 1 ? `${pathPrefix}/${index}` : `${pathPrefix}`
}

module.exports = async ({ graphql, actions: { createPage } }) => {
  /* ... */

  createPaginatedPages({
    buildPath,
    createPage,
    edges: posts,
    pageTemplate: blogTemplate,
    pathPrefix: '/blog',
    pageLength: 10,
  })
}