⚠️ This lesson is retired and might contain outdated information.

Build a Blog Post Template with GraphQL and Gatsby

Taylor Bell
InstructorTaylor Bell
Share this video with your friends

Social Share Links

Send Tweet
Published 6 years ago
Updated 2 years ago

In order to display the generated HTML from a Markdown post, we will build a GraphQL query and pass its data into a Template component that makes use of React’s dangerouslySetInnerHTML API to add a DOM element.

Instructor: [00:00] Inside of our gatsby-node.js file, we make a query that finds all of our files and then gets the path from the frontmatter. Then we cycle through all of them and call createPage, which creates a page for each of them using the blog post template component. It passes this context and path slug through to it.

[00:21] Over in our template, to see this in action, let's go ahead and console.log props. When we reload our page, we can see that our props have been logged out. Look at this. We have history, location match, page context, which has a path slug that matches what we passed through in Gatsby.

[00:43] In order to get the HTML for our blog post, we're going to write a GraphQL query that will search markdownRemark for the file that has a path of third post.

[00:53] Over in our blog post template, we'll do export const query = graphql. This will be with a tagged template. Use the query keyword. When we write a query, we can then get our path slug variable by doing $path slug. This is a string. The exclamation point means that it's required.

[01:13] What we'll be looking for inside of here is we're going to look for markdownRemark instead of allMarkdownRemark since we're only looking for one file. These are the parameters that we can use in our search.

[01:27] We want markdownRemark. We're looking for frontmatter where the path is equal to $path slug. We will want the HTML. We want the frontmatter. From the frontmatter, we want to get the title out. Save this.

[01:42] This all looks the same so far, but we now have data. Remember, data gets passed in as a prop to the component from the query. We can see our HTML. The frontmatter title was Post C.

[01:53] Now that we know that this stuff made it over OK, we can pull them out as variables. We can do const title = props.data.markdownRemark.frontmatter.title, a mouthful, and const html = props.data.markdownRemark.html.

[02:14] We can replace our placeholder text with a <div>. For now, we'll give it a class name of blogPost so we know that it shows up. What's interesting about this <div> is this will be self-closing.

[02:25] We're going to use React's dangerouslySetInnerHTML API. We pass in an object of __html. Its value will be html. This is going to render the HTML from the query.

[02:36] We can see that this is a <p> of blah, blah, blah that's been transformed from our remark file. If we inspect this, we can see that we have our <div> of blogPost and our <p> tag of blah, blah, blah.

[02:47] Let's refactor this to clean it up a little bit. We'll destructure data. We'll destructure markdownRemark from our data. Obviously, you could go further if you want to, but that's fine for now.

[02:57] Let's add a title. We have our title and our post showing up. We can click back to the home page. We see that all of our posts have pages now. Added a little bit of style. We're good to go.

Tony Catalfo
Tony Catalfo
~ 5 years ago

why doesn't this query work in graphiql?

query($pathSlug:String!){
  markdownRemark(frontmatter: {path:{eq:$pathSlug}}){
    html
    frontmatter{
      title
    }
  }
}    
Andrew Alekseev
Andrew Alekseev
~ 5 years ago

style={{fontFamily: 'avenir'}} should be inside h1 tag as:

<h1 style={{fontFamily: 'avenir'}}>
Markdown supported.
Become a member to join the discussionEnroll Today