Gatsby and GraphQL are great combinations for CMS integration, In this article, we are creating Gatsby and WordPress Tag-based pages and displaying tags on a single post detail page.
All this data for tags comes from the WordPress API of a blog and we are fetching the data with GraphQL queries in Gatsby.
This article is a continuation of our Gatsby and WordPress integration series, so you will see some code from previous articles.
Here is the Link for our previous two articles
1. Building a Powerful Blog: Mastering the Art of Gatsby and WordPress Integration
2. Building a Stunning Gatsby and WordPress Post Detail Page with GraphQL V2.29.0 API
This one our third article on Gatsby and the WordPress integration series.
So, in the previous article, we created a post detail page, and in this article, we are going to display tags based on that article.
Display Gatsby and WordPress Tags on Post Detail Page
We will update our GraphQL query to get the tags list of the specific post and will link it with a page that will display all the post coming from the WordPress API based on the tag that user click.
This is the query that gets the tags result, which we need to update on our post detail page.
This is how you will display the tags with the data object, and with the map operator, you can display each tag.
Here we are using a /tag/ on a link because we will create a page that opens all the posts on a page based on these tags.
Below is the complete code for our singPost.js file.
import React from "react";
import { graphql } from "gatsby";
import { Link } from "gatsby";
const SinglePost=({data})=>{
const post = data.wpPost;
const tags = data.wpPost.tags.nodes
return (
<div class="container">
<h1>
{post.title}
</h1>
<div dangerouslySetInnerHTML={{ __html: post.content }}></div>
<div>
Tags : <br/>
{tags.map((tag,i)=>(
<Link key={i} to={`/tag/${tag.slug}`}><u>{tag.name}</u><br/></Link>
))}
</div>
</div>
)
}
export default SinglePost;
export const query = graphql`
query($id: String!) {
wpPost(id: { eq: $id }) {
title
content
excerpt
tags {
nodes {
slug
name
}
}
featuredImage {
node {
sourceUrl
}
}
}
allWpPost(sort: { fields: [date], order: DESC } limit: 5) {
edges {
node {
id
title
excerpt
slug
featuredImage {
node {
sourceUrl
}
}
}
}
}
}
`;
Here is the output for the above code.
After clicking one of the post links from the home page.
One more thing, you should already know that these tags are coming from the API based on the specific post id, which we have already discussed in our previous article.
Now, it’s time to create a page that will display all posts associated with the specific tag we clicked.
Gatsby and WordPress Tag Template to Display All Tag-based Posts
First, we will create a template named tags.js inside the templates folder, now declaring the basic function for this template.
import React from "react";
const TagTemplate=()=>{
return (
<h1>Tag Based Post List</h1>
)
}
export default TagTemplate;
Inside your gatsby-config.js file it is important to specify the routes for our tag page, so we need to updated our gatsby-config.js file.
{
resolve: "gatsby-source-wordpress",
options: {
url: "https://npmrun.com/api/graphql", // Replace with your WordPress site's URL
includedRoutes: ["**/tag"],
},
},
Update this part with includedRoutes property, inside your plugin sections.
Now, we have to update our gatsby-node.js file, so that during the build process, Gatsby can generate pages for these tags-associated posts static files.
const tagResult = await graphql(`
query {
allWpTag {
nodes {
name
slug
}
}
}
`);
const tags = tagResult.data.allWpTag.nodes;
tags.forEach((tag) => {
createPage({
path: `/tag/${tag.slug}`,
component: require.resolve("./src/templates/tags.js"),
context: {
slug: tag.slug,
},
});
});
You don’t need to replace this complete file from the previous article, you have to add the above code inside gatsby-node.js file.
Now, it’s time to update our tags.js file to display all posts list associated with the tag you clicked.
Here is the updated file for tags.js
import React from "react"
import { graphql } from "gatsby"
import { Link } from "gatsby"
const TagTemplate = ({ data }) => {
const tag = data.wpTag
const posts = data.allWpPost.edges
.map(({ node }) => node)
.filter(post => post.tags.nodes.some(node => node.slug === tag.slug))
return (
<div class="container">
{posts.map(node => (
<div key={node.id} md={6} lg={6}>
<img
width="50"
height="50"
src={node.featuredImage.node.sourceUrl}
alt={`Blog Post ${node.id}`}
/>
<h4>
<Link to={`/${node.slug}`}>{node.title}</Link>
</h4>
<p dangerouslySetInnerHTML={{ __html: node.excerpt }}></p>
</div>
))}
</div>
)
}
export default TagTemplate
export const query = graphql`
query ($slug: String!) {
wpTag(slug: { eq: $slug }) {
name
slug
}
allWpPost(
filter: { tags: { nodes: { elemMatch: { slug: { eq: $slug } } } } }
) {
edges {
node {
id
title
excerpt
slug
featuredImage {
node {
sourceUrl
}
}
tags {
nodes {
slug
}
}
}
}
}
}
`
So similar to our singlePost.js file, instead of post id, here we are filtering the posts data based on the URI of the tag, generally called a slug.
If you see the gatsby-node.js file, you can see that we are generating static pages based on this slug.
So this is how Gatsby generates pages based on the path and takes the data from the component, which is basically our file path.
Here is the final output when you click on a tag on the post detail page and that will open a page with the tag’s slug and display all those slug-related posts.
So This is it, Here is the next article, for this Gatsby and WordPress API integration series.