Each Markdown file is parsed into a node of type MarkdownRemark . To query all markdown files in on query, we are using allMarkdownRemark . All frontmatter fields are converted into GraphQL fields.

To display each post let us create a new template that will be consistent in style and getting frontmatter from GraphQL query we have just seen. Inside the src directory, create a new folder called templates and inside it, create a new file called blogPost.js .

In this component, notice the new query postQuery we are creating. This query will help us to display our blog posts into the template. This query puts all the frontmatter we require in order to display blog post in the component Template 's props .

In above, I am fetching the title for each post and the HTML content. While rendering the output we get from the query, I am using dangerouslySetInnerHTML which is a React’s replacement for using innerHTML in the browser DOM. In general, setting HTML from code is risky because it exposes a user to a cross-site scripting (XSS) attack if used with sensitive data. Since we do not have any users (no login/signup system), I am just using it for content that is rendered as HTML from markdown.

We now have a template of how our blog post will look but we still haven’t configured a way to render and convert a blog post into HTML. That’s next. Open gatsby-node.js in the root of your project and add the following code.

We start by requiring Node’s path in order to fetch the blog post template. Notice the actions along with graphql as parameters when we are exporting createPages . Gatsby uses Redux internally to manage state. That's where actions come from. The object actions contain the functions and these can be individually extracted by using ES6 object de-structuring. It has pre-defined functions such as createPage , createRedirect , setWebpackConfig and so on. You can find all of them here.

We then make use createPage programmatically. There are two other ways other than the approach we are implementing. In our case, we need to read Markdown files.

Since our home page is still not done to display a list of blog posts you will have to visit each URL listed below in order to see the blog posts in action.

For the first post, visit: http://localhost:8000/first-post

For the second post, visit: http://localhost:8000/second-post

Try to modify the Template component and other fields from the frontmatter. Open src/blogPost.js .

To represent the changes, I have added the date in italics just before the content of the blog post and after the title. Visit any post’s URL and see it in action.

Adding Previous and Next Blog Post Links

For this feature to work with our blog, we are going to make use Gatsby Link component. It is a wrapper around @reach/router ’s Link component that adds enhancements specific to Gatsby and you can even use props such as activeStyle or activeClassName to add styling attributes to the rendered element when it matches the current URL. Just like how a normal routing component in React behaves. Open blogPost.js file and add this.

Notice how I am using span tags with attribute role to wrap emojis along with aria-label attribute. It is considered as good practice in Gatsby, React and you will definitely avoid any linting errors. Now to make the above code work, we need to modify the context in gatsby-node.js .

The context object now contains two keys called prev and next . We are also using index value of each post. If the index === 0 , there is not going to be any previous post since it is the first one. You cannot go to a previous post here. We are then using these new context properties in blogPost.js using pathContext .

Visit the first post and you will get the following result.

Display all posts on Homepage

Since all of our markdown posts are getting rendered into HTML correctly, the next and previous post feature working too. So let us move ahead and display all the blog posts on the home page. Not the complete posts, but a link to each one.

On visiting the Home page URL: http://localhost:8000/ you will get the following result.

Conclusion

We now have a functioning blog!

I challenge you to expand your own blog further by adding comments or tags functionalities. Gatsby has a lot to offer. You learn more about Gatsby at their official documentation.

And, if you building your own blog from scratch, I’m interested why. Let me know in the comments. :-)

You can find the complete code for this tutorial in the Github repo below 👇

Thanks to William Wickey for help editing.

Building A Web Or Mobile App?

Crowdbotics is the fastest way to build, launch and scale an application.

Developer? Try out the Crowdbotics App Builder to quickly scaffold and deploy apps with a variety of popular frameworks.

Busy or non-technical? Join hundreds of happy teams building software with Crowdbotics PMs and expert developers. Scope timeline and cost with Crowdbotics Managed App Development for free.