← All Articles

How to develop a Gatsby blog with Markdown

Eljon HoxaEljon Hoxa
Nov 4th 22

How to develop a Gatsby blog with Markdown

Are you looking to build a Gatsby website with markdown? This post will take you through the Gatsby development process, from creating the project to deploying it in production on AWS. We will talk about the benefits of using Gatsby and show how to set up markdown, configure Gatsby, and build an article for your demo website.

Understanding Gatsby

Gatsby is a React-based framework that is used to build websites and applications. You can use it for blogs, documentation, portfolios, business, media, and e-commerce websites.

What are Gatsby's benefits?

  • Markdown is a text-to-html conversion tool that allows you to write in an easy-to-read and easy-to-write plain text format. With the usage of markdown within Gatsby, you’ll be able to develop web page content.
  • Gatsby’s performance is significantly better than many standard web application frameworks. Gatsby decouples the back end from the front end and allows new and improved front-end technologies to load extremely fast. This is optimal for both usability and SEO.
  • Improved performance, scalability, and security are pre-built within the framework.
  • Gatsby uses React, which is a great choice for most front-end developers.
  • Gatsby is widely supported. It has plugins through which you are able to connect to external systems such as HubSpot, WordPress, and many others, which are being updated constantly.

Are there any drawbacks?

  • Even the simplest Gatsby site requires some development to set up, as opposed to some website builders that are entirely plug and play.
  • If you want to add a feature from another site, you'll need to custom code it.

However, the many advantages overshadow the drawbacks.

Getting Started

Let’s get started with the Gatsby blog development and design process!

Note: You can also visit Gatsby's official documentation for more information.

Gatsby Blog Development

When developing with Gatsby, we need to install Gatsby CLI. Open up your terminal and paste in the following:

npm install -g gatsby-cli

To create the project files, use the command below:

gatsby new

After this command has been entered, you will see instructions on how you can set up the Gatsby website. Follow along with the instructions. After completion, you’ll have your project folder.

Gatsby Project Structure

Let’s see the files that are within the project itself. You can either navigate to your project folder or use your terminal to open the folder location.

These are the files you should have:


├── README.md
├── gatsby-config.js
├── gatsby-node.js
├── node_modules
├── package-lock.json
├── package.json
├── public
├── src
└── yarn.lock

We will be focusing on the following: gatsby-config.js and the src directory.

gatsby-config.js is where all the customization, meta data, and tools will be added. src contains the resources which will be used and displayed on your website. These can range from images to videos and many other sources.

To view the blog which has been created, you can do gatsby develop.

If it has been done successfully, you’ll see the following message, which shows you the localhost URL of your development view.

Gatsby blog, gatsby-config.js

By default, http://localhost:8000/ is the main URL, but this can change depending on whether you have other development views open at the same time.

Gatsby blog view

The development view will auto-update with any changes that have been made, allowing you to see your changes in real-time. You won't need to refresh often to see your update.

Creating Gatsby Markdown

Create a folder within the src folder called pages. This folder will host our markdown article pages. To add your first markdown page, navigate to the pages folder and create a file within the folder called index.md.

└──src
    └──pages
        └── index.md

The index.md file should have a path, date, and title in the header (or “frontmatter”). These determine how and where articles are loaded on the website. However, depending on the structure of your website, you can develop your own frontmatter. Your frontmatter depends entirely on what you would like to display on the website. You could add a field called "Author", for example.

---
path: "/hello-world"
date: 2022-08-25
title: "Blog Post"
---
My first blog post!

We will now add two useful React tools remark and helmet to our project. remark will parse the markdown files and helmet will manage our document components such as title, description, path etc.

npm install react-helmet gatsby-transformer-remark

Once we’ve installed these, we can add both of them to our gatsby-config.js. The reason we are adding both of these is to tell the code the location of the pages.

, {
    resolve: 'gatsby-source-filesystem',
    options: {
      "name": "pages",
      "path": "./src/pages/",
    },
    __key: "pages"
  },
  `gatsby-transformer-remark`,

Creating Separate Article Pages

Now that we have a markdown file, we need to load it on our website. In order to do this, we create a file within the project folder called gatsby-node.js.

This file will contain code that builds links from our blog posts into standalone article pages.

We’re going to use the .createPages function to build each of the blog pages within our Gatsby website. Our markdown file will be parsed and, if there are no errors, a page will be created at the URL specified in our frontmatter.

The function then passes the results to blog.js, which formats the information to display it.

const path = require("path")

exports.createPages = async ({ actions, graphql, reporter }) => {
  const { createPage } = actions

  const result = await graphql(`
    {
      allMarkdownRemark(
        sort: { order: DESC, fields: [frontmatter___date] }
        limit: 1000
      ) {
        edges {
          node {
            frontmatter {
              path
            }
          }
        }
      }
    }
  `)

  if (result.errors) {
    reporter.panicOnBuild(`Error while running GraphQL query.`)
    return
  }
  const blogPostTemplate = path.resolve(`src/templates/blog.js`)
  result.data.allMarkdownRemark.edges.forEach(({ node }) => {
    const path = node.frontmatter.path
    createPage({
      path,
      component: blogPostTemplate,
      context: {
        pagePath: path,
      },
    })
  })  
}

Next we will create blog.js and posts.js in the src/templates directory.

└──src
    └──templates
        ├── blog.js
        └── posts.js

These two files handle the display of the blog posts, and the listing page.

In blog.js, we import graphql, helmet, and react. These tools allow us to parse information, create headings and render our post.

import React from "react"
import { Helmet } from "react-helmet"
import { graphql } from 'gatsby'

The function below renders the information parsed from the markdown file. The function will be used to post the title and blog content. However, to display the information, we will need to create posts.js.

export default function Template({ data }) {
  const { markdownRemark: post } = data
  return (
    <div className="blog-post-container">
      <Helmet title={`Your Blog Name - ${post.frontmatter.title}`} />
      <div className="blog-post">
        <h1>{post.frontmatter.title}</h1>
        <div
          className="blog-post-content"
          dangerouslySetInnerHTML={{ __html: post.html }}
        />
      </div>
    </div>
  )
}

export const pageQuery = graphql`
  query BlogPostByPath($path: String!) {
    markdownRemark(frontmatter: { path: { eq: $path } }) {
      html
      frontmatter {
        path
        date(formatString: "MMMM DD, YYYY")
        title
      }
    }
  }
`

Design & Display Your Article Page

Within the post.js page, we parse the information as usual, but we have an additional variable id. This variable is used to build up a list of blog posts to display.

export const pageQuery = graphql`
  query indexQueryAndIndexQueryAndIndexQueryAndIndexQuery {
    allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }) {
      edges {
        node {
          excerpt(pruneLength: 250)
          id
          frontmatter {
            title
            date(formatString: "MMMM DD, YYYY")
            path
          }
        }
      }
    }
  }
`

We import another tool named Link which converts the blog title to a link. The reason why we would need to have this field is so that when the user clicks on the title, it will direct them to the node-config.js which handles the blog page.

import React from "react"
import { Link, graphql } from "gatsby"
import { Helmet } from "react-helmet"

export default function Posts({ data }) {
  const { edges: posts } = data.allMarkdownRemark
  return (
    <div className="blog-posts">
      {posts
        .filter(post => post.node.frontmatter.title.length > 0)
        .map(({ node: post }) => {
          return (
            <div className="blog-post-preview" key={post.id}>
              <h1>
                <Link to={post.frontmatter.path}>{post.frontmatter.title}</Link>
              </h1>
              <h2>{post.frontmatter.date}</h2>
              <p>{post.excerpt}</p>
            </div>
          )
        })}
    </div>
  )
}

Bridging The Connection Between Files

We now have a complete backend for our Gatsby development blog. We can create posts using markdown, parse the markdown and render it as a page. Next we will list our blog posts on the main blog page.

First we need to import Link into our index.js to convert our titles to links.

Within our index.js, we will create an export function . This function lists our blog posts on the main page. After we have our export function, we will need to query our information again.

After all the information has been added to the main blog page, we will need to add ({data}) within our const design parameters as we need to pass the information to the front end.

After we have added the parameters, we will now add our export function. We will do this by creating a new heading. Once we have a heading, we can add our index function after the heading.

 </h2>
     <h2 style = {headingStyles}>
      Blog Posts!
  </h2>
      {Index({data})}

With all the code added and completed it should look like this:

import * as React from "react"
import { Link, graphql } from "gatsby"
import { Helmet } from "react-helmet"

const Design = ({data}) => {
  return (
    <main style={pageStyles}>
      <h1 style={headingStyles}>
        Gatsby Blog
        <br />
        <span style={headingAccentStyles}>Welcome to the basics of basic development.</span>
      </h1>
      <h2 style={headingStyles}> You'll See Avaiable Guides On basics. Updates are on real-time.
      </h2>
      <h2 style = {headingStyles}>
      Blog Posts!
      </h2>
      {Index({data})}
      <img
        alt="Gatsby G Logo"
        src="data:image/svg+xml,%3Csvg width='24' height='24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 2a10 10 0 110 20 10 10 0 010-20zm0 2c-3.73 0-6.86 2.55-7.75 6L14 19.75c3.45-.89 6-4.02 6-7.75h-5.25v1.5h3.45a6.37 6.37 0 01-3.89 4.44L6.06 9.69C7 7.31 9.3 5.63 12 5.63c2.13 0 4 1.04 5.18 2.65l1.23-1.06A7.959 7.959 0 0012 4zm-8 8a8 8 0 008 8c.04 0 .09 0-8-8z' fill='%23639'/%3E%3C/svg%3E"
      />
    </main>
  )
}

export function Index({ data }) {
  const { edges: posts } = data.allMarkdownRemark
  return (
    <div className="posts">
      {posts
        .filter(post => post.node.frontmatter.title.length > 0)
        .map(({ node: post }) => {
          return (
            <div className="blog-post-preview" key={post.id}>
              <h1>
                <Link to={post.frontmatter.path}>{post.frontmatter.title}</Link>
              </h1>
              <h2>{post.frontmatter.date}</h2>
              <p>{post.excerpt}</p>
            </div>
          )
        })}
    </div>
  )
}

export const pageQuery = graphql`
  query IndexQueryAndIndexQuery {
    allMarkdownRemark(sort: { order: DESC, fields: [frontmatter___date] }) {
      edges {
        node {
          excerpt(pruneLength: 250)
          id
          frontmatter {
            title
            date(formatString: "MMMM DD, YYYY")
            path
          }
        }
      }
    }
  }
`

export default Design

export const Head = () => <title>Blog Home</title>

Restart your development server, and your Gatsby blog website should look something like this! With this, your markdown blog is completed.

Gatsby blog view-2

Design, Deploy and Maintain Your Blog

UI with TailwindCSS

Design might be the hardest part of the process, as there are an infinite number of options for how your website can look and feel. To keep things simple I would recommend using TailwindCSS - it allows you to build nicely styled pages without messing with CSS directly. You’ll be able to find all the UI elements that you could include within your website.

Tailwind has a huge library of resources to help get you started. You’ll be able to find resources such as blogs, videos, documentation, and much more.

Note: Check out the official documentation on Tailwind. It contains everything you need to get going.

Deploy your Gatsby Blog with Cloud 66

Gatsby pairs extremely well with Cloud 66 as you will be able to configure and deploy your website every time a change has been applied to it without needing to manually copy the files or configure the environment.

Sign up for a Cloud 66 account

Navigate to the Cloud66 sign up page here: https://app.cloud66.com/users/sign_up

There are three options for creating a Cloud 66 account. You can use your GitHub, Google account, or sign up with your email and password.

Once you've entered your details, click on "Sign Up."

Connect Cloud 66 to your Git Repo

Next, if you created your account with email or Google, get started by connecting your git repository with your Cloud 66 account. You can skip this step if you've already connected with Github.

Next, choose a Gatsby repository from the drop-down and click the "Analyze" button. Cloud 66 has "read-only" access to your application, and it will return to you what we found about your application.

Connect your cloud provider with Cloud 66

Cloud 66 will ask you to enter your cloud provider API Key to give us the required access to deploy your blog for you.

Note: To host a static website, like Gatsby blog, you will need a cloud object storage service such as DigitalOcean Spaces, AWS S3, Google Cloud Storage, Linode Object Storage, or Azure Blob Storage.

Connect AWS with Cloud 66

Deploy!

Now hit the Deploy button and sit back and relax.

Deploy your Gastby blog with Cloud66

Congratulations, You’ve successfully deployed your Gatsby website!

Maintenance

Cloud 66 has a range of features to help you enhance and maintain your new Gatsby blog. For example:

  • preview deployments
  • traffic rules to control the traffic visiting your blog
  • failover groups
  • Team access control
  • LiveLogs and audit logs
  • Automated SSL certificates
  • Toolbelt (command-line interface).

All features are included and accessible to all members of your team at no extra cost.

Cloud 66 Toolbelt Deployment

The Cloud 66 Toolbelt is a command-line tool that uses an open-source API library. It allows users to manage and control their Cloud 66 applications. While it does allow users to access the open API, it expands the configuration options significantly. It’s available for MacOS, Windows, and Linux.

Cloud66 Toolbelt, cx redeploy


Try Cloud 66 for Free, No credit card required