Create your own blog site using Gatsby.js

Learn how to create your own static site easy without using a website builder

Content is King

Bill Gates

There are many reasons why you should blog. The main focus point of a blog is its content. And content is king. There are some options on where to post. However if you have decided to create a personal blog site then these are some of your options:

  • Use a content management system
  • Create you own website from scratch

In the past I have used WordPress. However as a developer I find it very frustrating how complex some of these content management systems are. Some of the drawbacks:

  • adding custom plugins requires some knowledge of the system
  • can be pretty slow for a such a simple use case
  • hosting can be expensive (£6.99/month or £83.88 per annum on Basic)

I just prefer programming it. And so program it I did.

2 weeks ago I decided to launch my own blog site. I used Gatsby.js. Gatsby.js is an open source framework to build static sites.

In this post:

  • I’ll answer why I chose Gatsby.js
  • I will show you how I built my site using Gatsby.js
  • I will show you how I deployed my site for free (without counting the price of domain register)

For this post some familiarity with web development (HTML, CSS, Javascript), Markdown, React.js and GraphQL would be beneficial. However you can learn and deep diver into the technology stack after the post too.

Why use Gatsby.js

Gatsby.js is a React based framework to create static websites. If that is all new to you know this:

  • React is a framework to write UIs in Javascript
  • Gatsby.js uses React as the tool to write UIs and then converts those into static HTML pages with its associated CSS files.

The user visiting your website then only fetches those files and renders it straight on the browser.

It’s simple. It’s fast. It’s perfect for a blog offering nothing more than content that does not change.

Assuming you are already familiar with web development or willing to learn then Gatsby.js is a great tool for your blog site.

Static vs Dynamic vs Single Page App website

I mentioned that Gatsby.js is framework to build static websites. That means that the code is converted to HTML and CSS once. Then those files are deployed and accessed by the visitor. What are the alternatives of serving a website? There is:

  • Dynamic websites
  • Singe Page App

Both of these options requires code to be executed to build the page.

With dynamic website the user requests the page and then the server executes code to build the website and then deliver the HTML and CSS files (and maybe some code to execute on the clients browser. The user will need to wait until the page is rendered and then send this back to the client.

As for Single Page Apps the server delivers code to executed on the clients web browser. The code then constructs the page. The code can be quite large at times so the user might need to wait for some time before the page renders.

These options have benefits when the page renders content that changes frequently between requests or offers customised experiences and services for the individual.

For a blog whose content changes only when you add a new post these are unnecessary.

Build a blog site using Gatsby.js

In this section we’ll take a step by step approach on building a blog site using Gatsby.js. We won’t delve into Javascript, React, HTML and CSS. I assume you are already familiar with the basics of web development.

Here are the steps we’ll take in this section:

  1. Adding posts to your site
  2. Making changes to the looks of your post
  3. Adding a contact page

Getting Started

Let’s begin by installing the tools we need to start developing the blog site. Gatsby.js uses Node.js. In simple Node.js is a tool to run Javascript code. Head to nodejs.com and install the latest LTS version (Long Term Support).

Open terminal and test your installation by running:

node -v && npm -v

Next let install Gatsby.js. Run the following command in the terminal:

npm install -g gatsby-cli

One last setup step is to initiate the project. We’ll use Gatsby’s CLI (command line interface) to create a template for us. Execute the following command in Terminal:

cd ~ && gatsby new my-blog-site https://github.com/gatsbyjs/gatsby-starter-blog

Next open the project in your favourite IDE or editor. I personally use Visual Studio Code, however there are plenty of other options out there.

Finally run the project. Execute the following command:

cd ~/my-blog-site && gatsby develop

The project is now ready to be developed. You can see the current state of the project by visiting http://localhost:8000/ on your browser.

Note keep this terminal window open during the post. This window will be running our site server. Execute any following commands within this post in a new terminal window.

The starter project will provide a template for the blog. In this post we’ll make some changes to the project. The aim here is to get you familiarised with how Gatsby works.

Next we’ll be looking at how to make changes. Open the project in your favourite editor.

1. Adding posts to your site

Exploring the project structure you’ll find blog posts under content > blog.

Each blog post is its own directory. Each post contains a file named index.md and some associated images used in these posts. This Gatsby template uses Markdown as the markup language for your content.

Let’s add our post. Under blog directory create a new directory named new-gatsby-post. Next under the new-gatsby-post add a file named index.md. You can create the new post using the command line:

cd ~/my-blog-site
mkdir -p content/blog/new-gatsby-post
touch content/blog/new-gatsby-post/index.md

Next open the file and add the following:

title: New Gatsby Post!
date: "2020-11-22T22:12:03.284Z"
description: "This is my first Gatsby Post!"
This is my first Gatsby Post!

Once you save the file your browser will automatically reload. The index page to your site will now list the post in the list of posts.

How did Gatsby list our new post already without any further actions than adding the file? It’s not magic. On simple terms Gatsby watches the project files. As files are changed or added to the project Gatsby rebuilds the site and locally deploys from where the local server serves your site.

2. Making changes to the looks of your post

The template project is a great starting point. But the one of the main drivers of building your own site is to give that custom look that defines you. In this step we’ll look at how to customise the feel and look of your site. Specifically your post page.

In the previous step we wrote our blog post in Markdown format. So how does Markdown become HTML and CSS files? Gatsby converts the Markdown file into HTML and CSS using a template file. In the project the blog post template can be found under src > templates > blog-post.js. Open the file in your editor of choice.

Let’s change the post to use a different colour for our post title. You’ll notice that template uses inline CSS. I’m not a fan of inline CSS so let’s create a new file to hold our blog post styling. Within src > templates create a file named blog-post.module.css:

Add the following to the file contents:

.title {
color: #818181;

Then on blog-post.js add the following line after import SEO from “../components/seo”:

import styles from "./blog-post.module.css"

Finally change <h1 itemProp=”headline”>{post.frontmatter.title}</h1> on line 27 to:

<h1 itemProp="headline" className={styles.title}>{post.frontmatter.title}</h1>

That’s all that is needed.

If you are wondering how Gatsby generates the post page keep on reading till the end of this step. Otherwise feel free to jump to the next step.

Upon launching or relaunching the server Gatsby calls a function named createPages on file named gatsby-node.js. Here we can return the pages to create for each post. This has already been done for you in the project template.

...// 1. Define a template for blog post
const blogPost = path.resolve(`./src/templates/blog-post.js`)
// 2. Get all markdown blog posts sorted by date
const result = await graphql(
sort: { fields: [frontmatter___date], order: ASC }
limit: 1000
) {
nodes {
fields {

// finally convert each post into an HTML and CSS files
const posts = result.data.allMarkdownRemark.nodes
if (posts.length > 0) {
posts.forEach((post, index) => {
const previousPostId = index === 0 ? null : posts[index - 1].id
const nextPostId = index === posts.length - 1 ? null : posts[index + 1].id
path: post.fields.slug,
component: blogPost,
context: {
id: post.id,

First we load the template. Then we fetch all of the Markdown posts using GraphQL–a query language. The markdown files are being inserted as entries into the database by Gatsby. We use GraphQL to fetch the list of posts and its contents. Finally we feed the Markdown contents and the template to fill to the createPage function.

3. Adding a contact page

In the previous two steps we have looked into adding a post which is automatically converted from Markdown. But what if you’d like to add a new page which is not a post?

In this section we’ll create a page for our visitors to know how to contact you.

Non-generated pages live under src > pages in this project. Let’s create a new file here and name it contact.js. You can also use Terminal to create the page by executing the following command:

touch src/pages/contact.js

Additionally let’s create an accompanying CSS file. Within src > pages create a new file named contact-me.module.css. If using Terminal execute the following:

touch src/pages/contact.module.css

Open contact.js and set the following as the contents of the file:

import React from "react"
import Layout from "../components/layout"
import { graphql } from "gatsby"
import styles from "./contact.module.css"const Contact = ({ data, location }) => {
const siteTitle = data.site.siteMetadata.title
return (
<Layout location={location} title={siteTitle}>
<p className={styles.contactBody}>Send me an email at myname@mysite.com!</p>
export default Contactexport const pageQuery = graphql`
query {
site {
siteMetadata {

Let’s lightly touch on whats going on here. We have created a page that uses the common layout of the site (layout.js). The layout components add the header and the footer of the site. Then we have added a simple paragraph to the contents.

Instead of adding the same header and footer to each page we reuse the Layout component which let’s us wrap some content around this header and footer. This saves us time and maintenance of applying the same … well layout to each page.

However the site title must be queried on each page. The data property is injected by Gatsby using with the pageQuery property contents. From here we fetch our siteTitle to the Layout component.

On the paragraph we have set the style class name (className={styles.contactBody}) to one we will define in our css file next. Open contact.module.css and add the following:

.contactBody {
font-size: 2em;

Save your files and then visit http://localhost:8000/contact on you browser.

Deploying your blog site

In the previous section we got familiarised with Gatsby works and how to develop our site using it. In this section we will deploy our Gatsby site.

We will:

  1. Deploy the site to cloud storage (AWS S3 Bucket)
  2. Speeding up the access to your site and securing the visitors connection with your site (AWS CloudFront)
  3. Forward the visitor of your domain to the site hosting (GoDaddy)

Except for the domain registrar everything above will be free.

I assume you already have a domain registered with GoDaddy and and have an AWS account.

1. Deploy the site to cloud storage (AWS S3 Bucket)

As the first step we’ll create an AWS S3 bucket. This a service from Amazon Web Services to host files. We’ll be using S3 to host our static HTML and CSS files.

From within your AWS account navigate to S3 Management Console.

From within Console click on Create bucket.

Next name the bucket my-blog-site. Uncheck all of the checkboxes under Bucket settings for Block Public Access. Check the acknowledgement checkbox to make the bucket publicly accessible. Then click Create bucket button at the end of the page.

Next you’ll need to install AWS CLI (Command Line Interface) which will allow you and Gatsby access the bucket via command line. Follow the instructions in the link to install AWS CLI.

You’ll need to configure AWS CLI to have access to your bucket. First create an IAM (Identity and Access Management) user.

Name the user my-blog-site. The user must have programmatic access checkbox enabled. Click Next. Then Create Group.

Name the group my-blog-site-group and check AdministratorAccess. Then click Create Group. Then click Next: Tags. Then Next: Review. Then Create user.

Take note of the Access key ID and Secret access key or just download the CSV file.

Next configure AWS CLI. Open terminal and execute the following:

aws configure

When prompted enter the AWS key ID and Secret access key. You can skip the other prompts for input by just tapping enter.

Next let’s set up Gatsby so it can deploy the site to the S3 bucket. At the root of the project run the following command:

npm install gatsby-plugin-s3

Then open gatsby-config.js and insert the following to plugins:

resolve: `gatsby-plugin-s3`,
options: {
bucketName: "my-blog-site",

And finally open package.json and insert the following line to scripts:

"deploy": "gatsby-plugin-s3 deploy"

That was a lot of steps but now we are finally setup. One last thing to finish off this step: Deployment. At the root of the project execute the following command:

npm run build && npm run deploy

2. Speeding up the access to your site and securing the visitors connection with your site (AWS CloudFront)

In this step we will setup AWS CloudFront. This AWS service caches or copies you site contents to multiple locations and then serves the files to the visitor of your website from closest location. Thus the files have to travel less distance to reach your visitor.

But speed is not the only thing CloudFront offers. Leveraging CloudFront we can establish a secure communication between the visitor and the server serving the files. Whilst the site does not contain any sensitive information it does protect you from an interceptor serving another website that is not yours. Additionally some browsers no longer allow non-secure connections or warns the user that the site is not secure and requires user acknowledgement to proceed. This is not great user experience for your site.

Before jumping into CloudFront let’s create an SSL certificates which CloudFront will use for securing the communication between the visitor and your site.

In AWS navigate to Certificate Manager. Then click Request Certificate.

Then request a public certificate.

Next add your domain name with www. and without. Then click Next.

Choose Email Validation. Then click Next. Then click Review. Then Confirm and Request. At this point you’ll receive email to your email address registered with your GoDaddy account owning the domain. Confirm that you are the owner of the site.

Next let’s setup CloudFront. On your browser navigate to AWS CloudFront and click Create distribution.

Next click Get Started under Web section.

Next select the Origin Domain Name as my-blog-site.s3…

Then change the Viewer Protocol Policy to Redirect HTTP to HTTPS.

Then under Alternate Domain Names add your domain again with www. and without.

Then under SSL Certificate choose Custom SSL Certificate and then on text field select the certificate you created at the beginning of this step.

Finally click Create Distribution.

Next go back to CloudFront console and take note of the Domain Name of the distribution just created. If you visit the Domain Name listed you should be able to view your blog site.

3. Forward the visitor of your domain to the site hosting (GoDaddy)

In the previous step we created a CloudFront distribution for our site hosted in S3 so that our visitors can access our site fast and securely. Next we want to forward the visitor of the domain to our CloudFront url. For example when the visitor visits my-blog-site.com we want to forward them to <CLOUDFRONT_ID>.cloudfront.net.

Next navigate to your GoDaddy account and under products select your domain DNS configuration.

Under Records edit CNAME www and point it to your CloudFront link. Click Save.

Then under Forwarding change domain configuration to Forward Type Permanent and Settings to Forward Only. Click Save.

And that’s it! 🎉 You might have to wait for a while until your domain forwards to your site (DNS record update can take some time to propagate).


In this post we have learnt:

  • How yo build a static website using Gatsby.js
  • How to deploy a static website using AWS
  • How to forward requests to your domain to AWS using GoDaddy

Final Notes

As an iOS developer I have sometimes found that many web tech stacks require a lot of learning. They are many very powerful tech stacks out there that can help you achieve so much. But in simple cases like these ones I haven’t found any tech stack easier to work with than Gatsby.js. I have been delighted.

If you are not a software developer and looking to learn and launch a simple website then I’d recommend starting with Gatsby.js.

P.S. I don’t apologise for my drawing skills 😉.

For more on software development follow me on Twitter or Medium!

Senior iOS Engineer @ Onfido. Writing weekly blogs on iOS and programming. Follow me to stay tuned!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store