ADDING FEATURES TO YOUR GATSBY SITE
Published: 2019-07-24 16:01:25

{% youtube T_XKDo-m4js%}

*This article was taken from the above podcast.*

Welcome to another edition of the Yolo Brolo podcast where we play with new technologies and you come around for the ride.

Last time we scaffolded a basic Gatsby CLI project that is pretty much empty and does nothing than display the default Gatsby contents. But we’d be continuing by adding some cool features to the site so it’s not just plain HTML, we will turn the project into a **blog**, add **markdown pages** and **syntax highlighting**.
## EXPLORING PROJECT FILES
Here, we’d be going over the contents of the scaffolded gatsby project we got from the previous tutorial.
### gatsby-config.js
This file holds some important configurations specific and also important to the entire project. Basically the information included in this file are the site meta-data which holds information about the site **title, description and author**. It’s important to note that these properties can be extended to include other relevant information you seem fit for the site. For our project this looks like:
```javascript
module.exports = {
    siteMetadata: {
        title: "Gatsby Default Starter",
        description: `Kick off your next, great Gatsby project with this default starter.
        This barebones starter ships with the main Gatsby configuration files you
        might need.`,
        author: "@gatsbyjs",
    },
    ...
}
```
Also, pre-bundled to this config file are plugins that are needed for the entire project and we would be exploring these plugins and their purpose. To learn more about most of the plugins it is recommended you do a google search on them and read them up on the official gatsby documentation page:
- **gatsby-plugin-react-helmet:** This plugin is basically concerned with Server Side Rendering using react, SEO and meta tags.
- **gatsby-source-filesystem:** This file is used to reading files from your local file system into the Gatsby project.
- **gatsby-transformer-sharp:** This plugin is involved with a lot of image process and according to the official documentation the plugin is used  to create ImageSharp nodes from image types (images in the Gatsby project) that are supported by an image processing library known as *Sharp*, the plugin as provides fields in their GraphQL types for processing images in a variety of ways including resizing, cropping, and creating responsive images.
- **gatsby-plugin-sharp:** Generally, this plugin is used by other plugins for image processing, as it provides image processing functionalities built on top of the Sharp image processing library.
- **gatsby-plugin-manifest:** This plugin is mostly concerned with adding Progressive Web Application (PWA) features and manifest files for offline use cases to the the Gatsby project.
### gatsby-browser.js
This file holds information on every API we would love to add to the project and make use of in the browser.
### gastby-node.js
This is where a lot of the generation takes place but in general this file will be used for creating pages for the site.
### gatsby-ssr.js
This file handles everything server side rendering on Gatsby.
### src
src is the source folder and most of the important stuff happen here, one of the important files here is the index.js file
- **index.js:** This is the main file used by Gatsby to build up your application. If you look closely, you’d discover it contains the contents served when we run **localhost:8000** or the netlify generated url for our deployed project.
Enter `$ gatsby develop` on the terminal (make sure you are in the project directory) which will enable Gatsby spin up a local server to serve your Gatsby project on "**localhost:8000**”. Also, from the terminal output you’d notice that we have an exposed graphql endpoint at "**localhost:8000/__graphql**” for having a look at the graphql queries.
## BUILDING A BLOG
It’s important to note that there are lots of starters and groups of plugins to help you achieve what we are about to do and you pretty much are free to check out Gatsby blog starters. But for the purpose of this tutorial we’d be building it from scratch just to see how it’s done and get our hands dirty. Also if you are trying things out with gatsby, always checkout the documentation as it’s a totally awesome one.
Doing a quick google search on gatsby markdown pages will quickly take us to the gatsby documentation on "**Adding Markdown Pages**” . We need the **gatsby-source-filesystem** plugin to add markdown support to our blog. 
First we have to create a **posts** folder within the **src** folder from which the plugin will read the markdown pages from. Next, we create a **my-first-post.md** file within the posts folder with the content:
```markdown
# Hello World
```
Next, we need to install the **gatsby-transformer-remark** plugin which will convert/transform the markdown pages to HTML. To install this plugin, stop the running gatsby server by clicking <kbd>CTRL + c</kbd> then run the following command:
`$ npm install –save gatsby-transformer-remark`
Once the installation is complete, we add an additional section to the **gatsby-config.js** under the `gatsby-source-filesystem` plugin file like so:
```javascript
module.exports = {
    …,
    {
        resolve: `gatsby-source-filesystem`,
        options: {
            name: `posts`,
            path: `${__dirname}/src/posts`
        },
    },{
        resolve: `gatsby-transformer-remark`,
    }
```
Next, we need to create a page template for the markdown file and add some frontmatter which includes some extra meta-data for adding extra stuff to the HTML files. The frontmatter always comes at the top of the markdown files like so:
```markdown
---
path: "/blog/my-first-post”
date: "2019-06-19”
title: "My first awesome gatsby blog post”
---
# Hello World
```
To add the template file for the markdown pages, we need to add a **templates** folder to the src folder and add the page templates there(the template is basically a react component making use of a graphql query), for our case we need to create a **postTemplate.js**. Add the following content to the file;
```javascript
import React from "react"
import { graphql } from "gatsby"
export default function Template({
  data, // this prop will be injected by the GraphQL query below.
}) {
  const { markdownRemark } = data // data.markdownRemark holds our post data
  const { frontmatter, html } = markdownRemark
  return (
    <div className="blog-post-container">
      <div className="blog-post">
        <h1>{frontmatter.title}</h1>
        <h2>{frontmatter.date}</h2>
        <div
          className="blog-post-content"
          dangerouslySetInnerHTML={{ __html: html }}
        />
      </div>
    </div>
  )
}
export const pageQuery = graphql`
  query($path: String!) {
    markdownRemark(frontmatter: { path: { eq: $path } }) {
      html
      frontmatter {
        date(formatString: "MMMM DD, YYYY")
        path
        title
      }
    }
  }`
```
The **pageQuery** variable holds the graphql query, based on the `$path` defined in the frontmatter and return the html (converted markdown) and frontmatter from the markdown page. The **Template** function receives the query result in an object parameter called **data**, that includes an object called **markdownRemark**.
This object contains the **frontmatter** and **html** that wew are going to destructure from the **markdownRemark** variable, finally the Template function basically renders the output of the deconstructed objects.
The **gatsby-node.js** page needs the following code to create our page:
```javascript
const path = require(`path`)
exports.createPages = ({ actions, graphql }) => {
  const { createPage } = actions
  const postTemplate = path.resolve(`src/templates/postTemplate.js`)
  return graphql(`
    {
      allMarkdownRemark(
        sort: { order: DESC, fields: [frontmatter___date] }
        limit: 1000
      ) {
        edges {
          node {
            frontmatter {
              path
            }
          }
        }
      }
    }
  `).then(result => {
    if (result.errors) {
      return Promise.reject(result.errors)
    }
    return result.data.allMarkdownRemark.edges.forEach(({ node }) => {
      createPage({
        path: node.frontmatter.path,
        component: postTemplate,
        context: {}, // additional data can be passed via context
      })
    })
  })
}
```
After adding the code, we can check out our new feature and the markdown feature by rebuilding the project and starting our local server by running `gatsby develop` on the terminal, then checking out the blog page using `localhost:8000/blog/my-first-post` (the endpoint used to access our page has been configured in the frontmatter of the markdown).
It is time to create, we can create another markdown page, we’d name **my-second-post.md**, We pass it the frontmatter configurations and makes it hold `# Hello world again!` as content, like so;
```
---
path: "/blog/my-second-post”
date: "2019-06-19”
title: "My second awesome gatsby blog post”
---
# Hello world again!
```
We move on to add some markdown code formatting syntax using the triple backticks like so;
```javascript
---
path: "/blog/my-second-post”
date: "2019-06-19”
title: "My second awesome gatsby blog post”
---
# Hello world again!
    ```
    const greeting = "Hello”;
    console.log(`${greeting} world` );
    ```
```
Navigating to `localhost:8000/blog/my-second-blog` we’d see the Hello world again! Heading and the markdown formatted block of code within the triple ticks in a gray background, but that is not the prettiest syntax and we’d need to add some fancy highlighting.  
To achieve the syntax highlighting we’d be using `gatsby-remark-prismjs` plugin for markdown. For the plugin to work we need to have `gatsby-transformer-remark` plugin installed (which we already have) and `gatsby-remark-prismjs` (which we will install shortly). To download and add the plugin to the project stop the running server using <kbd>CTRL + C</kbd> and run on the terminal:
> $ yarn add gatsby-remark-prismjs prismjs
This command will download the `prismjs` plugin and add all it’s dependencies to the project. In the **gatsby-config.js** file we add the following configurations;
```javascript
{
  resolve: `gatsby-transformer-remark`,
  options: {
    plugins: [
      `gatsby-remark-prismjs`
    ]
  }
}
```
It is also necessary to add add the prismjs css for the syntax highlighting feature to be complete.
We add the css by adding `require("prismjs/themes/prism-solarizedlight.css”)` to the **gatsby-browser.js** file. After saving the changes we have made, we spin up the server again by running `gatsby develop` on the terminal to see the effects of the prismjs plugin and css to our markdown pages. To make the styling a little bit more fancier and language specific, we can add **javascript** keyword after the three backticks in the **my-second-post.md** file, like so:
```Javascript
---
path: "/blog/my-second-post"
date: "2019-06-19”
title: "My second awesome gatsby blog post”
---
# Hello world again!
    ```javascript
    const greeting = "Hello”;
    console.log(`${greeting} world` );
    ```
```
Checking `localhost:8000/blog/my-second-blog` you’d discover the color effects are a bit different from earlier, and it looks really great now. The ease with which things are done in Gatsby is mostly because the ecosystem around Gatsby is quite big and a lot of things you’d need has mostly been done.
We can further add our own custom CSS styling to the project by creating a folder **styles** and create a **global.css** file, then we include the stylesheet in **gatsby-browser.js** file like so;
> require("./src/styles/global.css”)
 Then in our **global.css** file we add the following styles to see that it actually works:
```css
body{
  background-color: red;
}
```
Reloading our browser tab at `localhost:8000/blog/second-blog-post` we’d discover that it actually works! Now we can go ahead to delete the codes and add the following code to make our line highlighting in our markdown pages possible;
```css
.gatsby-highlight-code-line {
  background-color: #feb;
  display: block;
  margin-right: -1em;
  margin-left: -1em;
  padding-right: 1em;
  padding-left: 0.75em;
  border-left: 0.25em solid #f99;
}
```
Then in the **my-second-post.md** file add `{2}` to the javascript keyword to highlight line two of the code block, like so;
```javascript
---
path: "/blog/my-second-post”
date: "2019-06-19”
title: "My second awesome gatsby blog post”
---
# Hello world again!
    ```javascript{2}
    const greeting = "Hello”;
    console.log(`${greeting} world` );
    ```
Checkout `localhost:8000/blog/my-second-post` and you’d discover that the second line of the code is highlighted! There are a lot of other styles we could also add to the markdown files.
## WRAP UP
We touched the different gatsby files of a typical gatsby project, the config files, the pre-bundled plugins and the graphql queries.
What's cool about Gatsby is that everything is statically rendered from the server, but once the page loads gatsby bootstrap up a spar and load the rest of the page dynamically and won’t request from the server everytime you reload.

Most of all the codes added to our project where lifted from the Gatsby official documentation and it’s a good practice to checkout the official Gatsby documentation when you are in doubt.

*This article was written by Opara Prosper who is a freelance writer.*  

*Need JavaScript consulting, mentoring, or training help? Check out our list of services at [This Dot Labs](https://thisdot.co).*