Build Your Own Blog Using Gatsby and React

May 24, 2018 0 Comments

Build Your Own Blog Using Gatsby and React

 

 

When people want to learn something new, especially a new programming language/framework/library, they usually go to these three places:

  • Official Documentation
  • Tutorials
  • Blog Posts

Being a software developer trainee myself, I know firsthand how much time one spends in searching the internet looking for answers to their questions.

The great thing about blog posts is that they are usually written by people who have faced the problem and want to share their experience and solutions with the rest of us. Thank God that Medium makes this never ending search a little bit easier.

We know how to write blogs. But can I create my own blog?

With Gatsby, a static site generator for React, we can easily create our own blog and do so at no overhead cost!

  • Gatsby
  • React
  • Markdown
  • GraphQL
  • GitHub

Let’s start building our app by creating a new Gatsby project. If do not have Gatsby installed on your system, use NPM to do so.

$ npm install -g gatsby-cli

Once the installation is complete, create a Gatsby project by typing the following command in the terminal.

$ gatsby new comic-blog
$ cd comic-blog

comic-blog is the name of my project. You replace it with anything else that you desire. We need to install a couple more dependencies to this project.

yarn add gatsby-source-filesystem gatsby-transformer-remark

Gatsby-Source-Filesystem creates File nodes from the file system, whereas Gatsby-Tranformer-Remark will transform any Markdown(.md) files into MarkdownRemark nodes, making it easier to query them.

Open the project in a code editor. I like to use VS Code. There, you will see the file structure of the project to be something like this:

Open gatsby-config.js file and add the dependencies that you just installed into this file.

With that, we are all set to go ahead and starting writing our blog posts.

In your code editor, src/pages is the place where Gatsby will go looking for markdown files. I am going to create my blog posts about DC Comics, starting with the DC Rebirth #1. So let’s create a folder called DC Rebirth #1, and inside it create a file named index.md.

Gatsby converts the front matter of a markdown file usable HTML data. Open the index.md file that you just created and write the following in it:

---
path: '/dc-rebirth'
date: '2018-05-23T12:34:00+00:00'
title: "DC UNIVERSE - Rebirth"
tags: ['The Flash', "Batman", "Superman", "Wally West", "Wonder Woman", "DC"]
excerpt: "It all begins here. Do not skip to the last page. Do not let a friend or message board ruin this comic for you. The future (and past) of the DC Universe starts here. Don’t say I didn’t warn you!"
---
(Start writing your blog post from here)

Here, I have added a path that Gatsby is going to use as the URL to access this post, a date using Unix TimeStamp, a title for the blog post, a tag containing a list of keyword that I will be able to use to search for the post, and a small summary that I will show on the Blog’s main page. After that, you can write your blog post like a regular markdown file.

Repeat this process for the rest of your blog posts.

Once done, you can launch this project using gatsby develop command from your terminal.

If you take a look at your blog in the browser, you will see that Gatsby is not displaying the blog post that you have created.

This is because, Gatsby still does not know where these blog posts are or that you even want them to be displayed in the browser.

Gatsby uses GraphQL to create a query that will be used by Gatsby to search for the blog posts.

Go to src/pages/index.js write the following code:

To understand what exactly is happening here, take a look the GraphQL query that I have named query. Not unimaginative at all!

This query named query is going to take in all the Markdown files inside the src folder. It will then give out the total number of markdown files (totalCount) and set up edges containing node.

The edge is a file system path to the node. Here node is nothing but our blog post. This node will have a unique id and all the frontmatter data like title, date, path, tags, and excerpt that we have defined earlier in the blog post’s markdown file. This data is then taken into the Indexpage component.

If you go back to your Blog in the browser, you will see that it is now displaying your blogs.

But if you click on the title, you will not be taken to the Blog post. Instead you will get to the 404 error page, that comes predefined within the project. We will see how to fix this issue.

In order to make Gatsby display your blog post, we need to pass the blog post’s data into a template component built using React.

Inside your src directory, create a new folder called templates. I will create my template component inside this folder and name the file as blog-post.js and write this code inside it.

react-helmet is a React component that can be used to manage any changes to the document head. I use this component here in the Template component to get a dynamic title of the blog post.

Another thing to note in this component is the div with dangerouslySetInnerHTML API. I am using it here to render the HTML that is being created by Gatsby from the markdown file.

I have create a new GraphQL query called pageQuery. This query is what will actually put our posts into the template. This query in turn contains another query called BlogPostByPath. This will get us the html and the frontmatter data.

As mentioned earlier, we will get a 404 page if we click on the title of our blog posts. This is because the blog post’s HTML page has not been built yet.

Gatsby builds our pages using the createPages API.

In the root of the project, you will find a file named gatsby-node.js. Delete the contents of the file and write the following inside it:

I require Node’s path module in order to access the local file system of our project. Next, I use the createPage API to bring in our blog post template that we had created earlier.

I have also created a GraphQL query that returns the markdown file’s html, id, and frontmatter. Once we get the result from the query, I use the createPage API to create a new page for each of the posts in our project.

If you go to your blog in the browser and click on the title of the post, you will get the blog post!

Note: If you still get the 404 page, then restart the gatsby develop command in your terminal. You may also delete the .cache folder in your project, just to be on the safer side.

createPage allows one to pass any additional data through context.

Here, I will add a processing step to include include links between posts, and update the template to display these links wherever appropriate.

Go to gatsby-node.js file and add index to the forEach loop. Also add the context object after the component. This object contains two keys called prev and next.

posts.forEach (({node}, index) => {
createPage ({
path: node.frontmatter.path,
component: blogPostTemplate,
context: {
prev: index = 0 ? null : posts[index - 1].node,
next: index
= posts.length - 1 ? null : posts[index + 1].node,
},
});
});

Next, we need to make a few updates to the blog-post.js file. First, destructure the pathContext inside the Template component, and then destructure next and prev from the pathContext.

const Template = ({data, location, pathContext}) => {
const {markdownRemark: post} = data;
const {frontmatter, html} = post;
const {title, date} = frontmatter;
const {next, prev} = pathContext;
...
}

We then add the next and prev links right below the div with the dangerouslySetInnerHTML API.

<p>
{prev &&
<Link to={prev.frontmatter.path}>
Previous: {prev.frontmatter.title}
</Link>
}
</p>
<p>
{next &&
<Link to={next.frontmatter.path}>
Next: {next.frontmatter.title}
</Link>}
</p>

Restart gatsby develop, reload the page, and you will find the next and prev links at the bottom of the blog post.

If prev link is not visible, its because it is the first blog post in your blog’s list. Similarly if next is not visible, its because it is the last blog post in your blog’s list.

If you take a look at the frontmatter of your blog post, you will see that we have something called tags. Tags can be used to group the blog posts.

Create two new files inside templates folder. Name them as tags.js and all-tags.js.

Write the following code inside all-tags.js file.

We destructure the pathContext from our props and pull the tags out of it. We then map over the tags to create a bullet list. Each item in the list is a link to the tag. The tag.js file will be similar to this.

Here, I am pulling out the posts and tagName out of the pathContext. Now, if there any posts related to a particular tag, we list them out in an unordered list.

We then need to make a few changes to the gatsby-node.js file. First, call a function called createTagPages. This will contain the createPageAction and posts.

createTagPages (createPage, posts);

We also need to define this function as follows:

The first thing we do here is bring in our tagPageTemplates and allPageTemplates. We also set up an empty object called postsByTags.

We then de-structure out each node. We only need to do something if there are tags. So, for each tag, we see if it’s already in the object. If it is not, we add it and push the node into the tag.

We then go ahead and create a tags variable that contains a list of every tag present in our markdown file. We then call the createPage to build an index of all the tags. The path is /tags, the component is allTagsTemplate, and the context has a sorted list of all of our tags.

We then build the individual tag pages. For each of our tags, the posts array will be pulled from the posts by tags. We call createPage for each, put the tag name as the path. The component is the tags template. For context, we pass the posts and the tag name for the specific tag.

Now that we’re processing all of our tags, we need to update our index page in order to show the tags.

Inside the pages/index.js file, we set up an unordered list that maps over post’s tags. We then return a <li> that contains a link to the tag.

<ul>
{post.frontmatter.tags.map (tag => {
return (
<li>
<Link to={/tags/${tag}}>
{tag}
</Link>
</li>
);
})}
</ul>

Restart the gatsby develop command and you will see the list of tags below each blog post.

If you click on any of the tags, you will be redirect to a new page contains blog posts that have that particular tag in their frontmatter.


Tag cloud