What we’re going to do
Get related posts to make the so-called ‘related posts’ section in a blog. Showing related posts would decrease the bounce rate and eventually help SEO by improving average engagement time and PV.
With Gatsby, we use Graphql query to get related posts.
It would be better if we had some logic to evaluate which post is more related, but this time we just get posts that have the same tag as the original post.
Premise
I assume we have the following post format,
blog.md
---
title: "blog title"
description: "blog description"
tags: ["tag1", "tag2", ...]
---
and query looks like this.
// blogPost.js
export const BlogPost = () => {
// ...
}
export const pageQuery = graphql`
query BlogPost($id: String!) {
markdownRemark(id: { eq: $id }) {
id
frontmatter {
title
description
tags
}
}
}
`
Create a custom resolver
To get the filtered posts by tags, we create a new resolver. With Gatsby, we can do that using the createResolvers API in gatsby-node.js file.
// gatsby-node.js
exports.createResolvers = ({ createResolvers }) => {
const resolvers = { /* your resolver */ }
createResolvers(resolvers)
}
This time, the resolver ends up like this.
// gatsby-node.js
exports.createResolvers = ({ createResolvers }) => {
const resolvers = {
MarkdownRemark: {
relatedPosts: {
type: ['MarkdownRemark'],
resolve: (source, args, context, info) => {
return context.nodeModel.runQuery({
query: {
filter: {
id: {
ne: source.id,
},
frontmatter: {
tags: {
in: source.frontmatter.tags,
},
},
},
},
type: 'MarkdownRemark',
})
},
},
},
}
createResolvers(resolvers)
}
In the resolver, we defined a new field relatedPosts in markdownRemark. And relatedPosts should be an array of markdownRemark so then specified the type as type: ['MarkdownRemark']
.
In the function resolve(), it’s specified to only get posts that have the same tag as the original post among all MarkdownRemark type. To avoid getting the original post itself, exclude the same ID post.
id: {
ne: source.id,
},
That’s it!
Let’s update the query and now we can get related posts.
// blogPost.js
export const BlogPost = () => {
// ...
}
export const pageQuery = graphql`
query BlogPost($id: String!) {
markdownRemark(id: { eq: $id }) {
id
frontmatter {
title
description
tags
}
relatedPosts {
frontmatter {
title
}
}
}
}
`