Sayed's Blog

Adding Next And Previous Links in a Gatsby Blog

Posted August 31st, 2019

My blog mostly follows the intermediate Gatsby tutorials. This was my "gatsby-node" before adding previous and next articles.

exports.createPages = ({graphql, actions}) => {
    const {createPage} = actions;
    return graphql(`
    {
        allMarkdownRemark {
            edges {
                node {
                    fields {
                        slug
                    }
                }
            }
        }
    }
    `).then(result => {
        result.data.allMarkdownRemark.edges.forEach(({ node }) => {
            createPage({
                path: "posts" + node.fields.slug,
                component: path.resolve(`./src/templates/blog-post.js`),
                context: {
                    slug: node.fields.slug
                }
            })
        });
    })
}

Foreach takes an index as an optional parameter. I used this to get the previous and next articles.

result.data.allMarkdownRemark.edges.forEach(({ node }, index, lst) => {
	let next = index > 0 ? lst[index-1] : null;
    let prev = index < lst.length - 1 ? lst[index+1] : null;

It also takes in the array it is iterating on as an optional parameter. Since the first post does not have a previous post, and the last post does not have a next post, I have to check if they exist.

To pass them in to an individual post, I pass them in as context to the createPage function:

createPage({
                path: "posts" + node.fields.slug,
                component: path.resolve(`./src/templates/blog-post.js`),
                context: {
                    slug: node.fields.slug,
                    next: next ? next.node.fields.slug : '',
                    prev: prev ? prev.node.fields.slug : '',
                }
            })

Which I destructure in the post template component.

export default ({ data, pageContext}) => {

And use to create links to the previous and next posts:

<Link to={'posts/' + pageContext.prev}>
    Previous
</Link>

<Link 
    style={{float: 'right'}}
to={'posts/' + pageContext.next}>
    Next
</Link>

Unfortunately, this was not enough. The query I use to create the pages does not return the posts in date order. So the previous and next links were not referring to posts that where chronologically before or after. To fix this, I had to modify the query to sort by frontmatter date, similar to the query for the posts listing page.

allMarkdownRemark(sort: {order: DESC, fields: [frontmatter___date]}) {

This was enough to get it working.

PreviousNext