in

Gatsby + Strapi: Query For Specific Post

Query For Specific Post Using Slug

Most of the data queries are very straightforward. However one of the critical things that we are going to have to do over and over again is to filter a query with arguments so that we can pull out a specific piece of data.

For example when we are using the single post query, we need to use the slug as an id and pull in just that post into our create page function.

We can start by constructing a query with the data we want to grab.

Note that we are grabbing a single post, not all posts. And if we run this it will just pull in the first post that it finds. But we want to filter based on the slug. Here is how we do that.

Immediately after our node type (strapiPost) we can insert some arguments. You CAN place them all on one line, but it is very common to break it out into multiple lines.

Then inside of that we specify Slug because we are filtering based on the slug and then eq, short for equals, which takes a string. We can then put in the string of an existing slug and if we run that we see that it pulls up the post with that specific slug.

The next step is to replace the string with a variable, because we need to dynamically filter, not manually make a query for every post. To do that we use the query variables tool in GraphQL Playground to specify a variable. In this sample slug=test-post. Then just behind our query we add our variable and specify that it is a string.

Then we can replace the hard-coded slug with $slug variable.

And in our application the correct post will be queried!

import React from "react"
import { graphql } from "gatsby"
import ReactMarkdown from "react-markdown/with-html"


// pull post data based on slug
export const query = graphql`
  query($slug: String!) {
    strapiPost(Slug: { eq: $slug }) {
      Title
      Date (fromNow: true)
      Content
    }
  }
`
// insert post data component
// markdown rendering: https://www.npmjs.com/package/react-markdown
const Blog = props => {
  console.log(props.data);
  return (
    <div>
      <h1>{props.data.strapiPost.Title}</h1>
      <p>{props.data.strapiPost.Date}</p>
      <ReactMarkdown source={props.data.strapiPost.Content} escapeHtml={false} />
    </div>
  )
}

export default Blog