Reputation: 1633
I am working on a blog using Gatsby and I am trying to generate pages based on that tag a user clicks on.
When a user clicks on a tag, he should be redirected to a page that displays a list of articles with that tag.
I created a query that does that. However, my GraphQL query works in my GraphQL editor but not in my react code. It returns an empty array in the code but the expected result when I run the query in the Graphql editor.
import React from "react"
import ArticleCard from "../articleCard/ArticleCard"
import Pagination from "../pagination/Pagination"
import articlesStyles from "./Articles.module.scss"
import { useStaticQuery, graphql } from "gatsby"
const Articles = ({ pageTitle }) => {
const blogPosts = useStaticQuery(graphql`
query($tag: String) {
allMarkdownRemark(
sort: { order: DESC, fields: [frontmatter___publish_date] },
filter: { frontmatter: { tags: { in: [$tag] } } }
) {
nodes {
frontmatter {
title
publish_date
imageUrl
author
category
}
fields {
slug
}
excerpt(pruneLength: 100)
}
}
}
`)
const nodes = blogPosts.allMarkdownRemark.nodes;
console.log(nodes)
return (
<div className={articlesStyles.contentArea}>
<h1 className={articlesStyles.headerTitle}>{pageTitle}</h1>
<div className={articlesStyles.articles}>
{nodes.map(node => {
return (
<ArticleCard
key={node.id}
{...node.frontmatter}
excerpt={node.excerpt}
slug={node.fields.slug}
/>
)
})}
</div>
<Pagination />
</div>
)
}
export default Articles
Upvotes: 1
Views: 568
Reputation: 8162
As @xadm and @ksav noted in their comments:
"Known Limitations useStaticQuery does not accept variables"
Query for all blogs, then use Array.prototype.filter() to get the one you need:
// ...
const blogPosts = useStaticQuery(graphql`
query {
allMarkdownRemark(
sort: { order: DESC, fields: [frontmatter___publish_date] }
// you can't filter here
) {
nodes {
frontmatter {
title
publish_date
imageUrl
author
category
}
fields {
slug
}
excerpt(pruneLength: 100)
}
}
}
`)
// Get all blogs
const { blogPosts: { allMarkdownRemark: { edges } } } = props;
// filter the blogs
const yourFilteredTag = edges.filter(
el => el.node.childMarkdownRemark.frontmatter.tag === yourTagVariable);
// Now you can get the filtered list of blogs
console.log(yourFilteredTag);
// ...
As @Albert Skibinski mentioned this solution is not scalable. The context in gatsby-node.js
might be a better solution in your use case.
The Array.prototype.filter() solution I described should be reserved for components where the context
variable is not available and you can make sure that the size of the array does not grow excedeedingly large.
Upvotes: 1
Reputation: 499
As mentioned in the comments, you can't use variables in a staticQuery.
However, this may change in the future as many people stumble upon this limitation and there is work in progress to provide 'dynamicQueries'.
In the meanwhile you can use variables in queries in gatsby-node.js and the templates used by the createPage
API. So, in your case, you could generate all the pages for all the tags in gatsby-node.js and still use the same article.js as component template.
See: https://www.gatsbyjs.org/docs/adding-tags-and-categories-to-blog-posts/
Upvotes: 1