An Overview of Gatsby Plugins & GraphQL

Note: This is part 3 of four-parts Learning GatsbyJs series. This learning post is still in active development and updated regularly.

In the previous part 2 of the four-parts series, step-by-step procedures to extend & modify the ‘hello world‘ site components to add new pages, styling site, adding global shared components like <Layout /> with header, footer and other components were discussed. In this series, installing & configuring Gatsby plugins to extend the site to get content data & transform functionality will be over-viewed with a working case example.

Learning series
Part 1: Learning GatsbyJS – Setup & Installation
Part 2: Understanding GatsbyJS Building Blocks
Part 3: An Overview of Gatsby Plugins & GraphQL (this post)
Part 4: Learning to Programmatically Create Pages in Gatsby

The objective of this learning-note post series is to explore GatsbyJs to build an simple SPA blog site and document step-by-step procedures to install & setup Gatsby and overview of its data layer.

Goal

The main goal of this learning-note post is to get an overview of Gatsby data layer. How data in React components from local or external APIs are fetched is described in a previous post. But in Gatsby it makes use of GraphQL a query language to fetch data from local & external APIs together with Gatsby plugins. To quote Gatsby tutorial doc “Gatsby uses GraphQL to enable components to declare the data they need.”

GraphQL Use in Gatsby

GraphQL, a data query language, was developed by facebook to solve their need to fetch the only the needed data from the external APIs. Gatsby uses this GraphQL, a popular & powerful technology to load desired data into its React component.

Send a GraphQL query to your API and get exactly what you need, nothing more and nothing less. GraphQL queries always return predictable results. Apps using GraphQL are fast and stable because they control the data they get, not the server. Source: GraphQL

In Gatsby, GraphQL is used to query data using a special syntax from its internal files as well as from external third party APIs. The GraphQL serves as a interface between Gatsby and its data sources.

To quote from Gatsby docs “GraphiQL is the GraphQL integrated development environment (IDE). It’s a powerful (and all-around awesome) tool you’ll use often while building Gatsby websites.

In the next section, some use case examples of GraphQL is discussed while using few Gatsby plugins.

Note: More detail discussion on GraphQL use in Gatsby will be discussed in a separate post Deep Diving into GraphQL use in Gatsby (in preparation).

Gatsby Plugins

Gatsby plugins are Node.js packages and are install using NPM. Gatsby utilizes JAMstack (JavaScript, APIs & Markup) to build projects.

Gatsby plugins library is robust to extend & modify functionality of GatsbyJs core. There are three categories of plugins:

  • Source Plugins: Data in Gatsby sites can be from internal local files and/or external databases, APIs, CMSs, etc. The source plugins fetch data from their sources. This plugin adds nodes in Gatsby data system and thus permits data transformation with transformer plugins into usable format. For example, if we would like to fetch data from local files, the gatsby-source-filesystem plugin knows how to fetch data from file system. Similarly, the gatsby-source-wordpress plugin fetch data from WordPress API.
  • Transformer Plugins: The data fetched from source plugin are in various file format. The transformer plugins transform the fetched raw data by the source plugins into usable format to build Gatsby sites. For example, gatsby-tranformer-remark plugin transforms data in markdown files into HTML to display in a browser.
  • Functional Plugins: These groups of plugin extend functionality of Gatsby. For example, gatysby-plugin-react-helmet enhances Gatsby functionality with react-helmet to manipulate head of Gatsby document (eg, to add SEO etc.,).

In Gatsby sites, most contents are created with markdown, GraphQL to query markdown files (eg. API) and delivery using React components.

In this learning-note posts, the following two Gatsby source and Gatsby transformer plugins will be installed and explored to extend the Gatsby site project. To get started, the following two plugins will be install with npm in project folder:

#! install plugin in project folder
npm install --save gatsby-transformer-remark  gatsby-source-filesystem

Gatsby transformer remark: This plugin uses Remark library & ecosystem to parse markdown files in .md format into HTML.

Gatsby source filesystem: This Gatsby source plugin parses files within a directory for further parsing by other plugins & help to read the markdown files.

Configuring Plugins

Most plugins have their default configuration but can be customized by overwriting with options.

Installing Working Example Site

To start fresh, a new site named ‘hello-plugin‘ was setup with the Gatsby default starter hello-world as described previously.

Starting Point

As a starting point, the site was setup similar to described in the previous post with a shared <Layout /> component and three page components. The commonly use section of the sites (header, main navigation, footer) and global styles included in layout.js component as shown below:

Figure: Screenshot showing project site’s file structure (left), layout.js (middle) and header.js components as described in the previous post.
The <Layout /> & <Header /> Components

To refresh, the <Layout /> and refactored <Header /> components from the previous posts are shown in the middle-panel & right-panel, respectively (above). A browser display of starting point of the project site is shown below:

Figure: Screenshot of project site with shared header.js, footer.js and layout.js components with basic styling.

Extending With Plugins & GraphQL Query

Some common site data like site title, description, author etc., can be added as siteMetadata object at one location at gatsby-config.js located at the root of Gatsby site project. These data can be accessed from other components by referencing that location.

1: Editing gatsby-config.js File

Some basic site data like title (for entire site), pagetitle (for page), description are added in gatsby-config.js file as shown below.

// gatsby-config.js
module.exports = {
  siteMetadata: {
    title: 'Hello siteMetadata',
    pagetitle: `Title from siteMetadata`,
    description: 'Gatsby - Learning by Doing!',
  },
   plugin:  [ ],
}

After restarting development server, the above information stored in siteMetadata object is available for refrence from Gatsby page components with GraphQL query.

2: Using Page Query

In the example below, pagetitle data stored at siteMetadata object in gatsby-config.js is available for reference using GraphQL query and the query results can be mapped in a page (eg., about.js) component.

// page query example
import React from "react"

import { graphql } from "gatsby"
import Layout from "../components/layout"

export default ( {data} ) => (
  <Layout> 
    <h1>This {data.site.siteMetadata.pagetitle}</h1>  
    <p>Content for about page. A react way!</p>
    <img src="https://source.unsplash.com/600x300/?cat" alt="" />
  </Layout>
)
// page query
export const query = graphql`  
  query {    
      site {      
         siteMetadata {        
              pagetitle      
        }    
      }  
   }`

In the example above, pagetitle data location in siteMetadata is referenced (line: 9) in a page component (eg., about.js). The GraphQL is imported to the page component (line 4) then the graphql query for pagetitle is appended in the component (lines: 15-22).  Its output in the browser is shown in the figure below.

Additional Information: Use a page query | Gatsby Tutorial

3: Using StaticQuery

The Gatsby’s StaticQuery was introduced as new API in Gatsby V2 to allow non-page component to retrieve data with GraphQL query. In the example below, its hook version – useStaticQuery is used to reference site title data stored at siteMetadata object by referencing in src/components/header.js component, as described in the Gatsby tutorial.

//src/components/header.js
import React from "react"
import { useStaticQuery, Link, graphql } from "gatsby"
import "../styles/header.css"

export default ( ) => {
     const data = useStaticQuery(    
       graphql`      
       query {        
         site {          
           siteMetadata {            
             title          
            }        
          }      
        }    
        `  
        )  
      return (
  
    <section className="header">
    <div className="site-title wrapper"> 
      <Link to="/">
        <h3>{data.site.siteMetadata.title}</h3> 
        </Link>
      <ul className="menu">       
        <Link to="/">Home</Link>        
        <Link to="/about/">About</Link>        
        <Link to="/contact/">Contact</Link>      
    </ul>
  </div> 
  </section> 
)
}

In the example above, the useStaticQuery was imported from Gatsby (line 3). Then using GraphQL, site title graphql query was defined in header.js component (lines: 7-16) and the title data from siteMetadata was referenced  in line 23. Its output displayed in the browser is shown in the figure below.

Additional Information: Use a StaticQuery | Gatsby Tutorial

4: Viewing in a Browser

Restart the development server and open up the browser at localhost:8000 and view output from above queries.

Figure: Screenshot showing result of page query in site title & staticQuery in page title from gatsby-config.js siteMetadata.

Extending with Source Plugins

In this section, we will explore using gatsby-source-filesystem plugin & GraphQL to full data from a Gatsby site.

Step 1: Plugin Installation

Install source plugin gatsby-source-filesystem at the root of the project with npm or yarn, as shown below:

#! install with plugin
sudo npm install --save gatsby-source-filesystem
#! install with yarn
sudo yarn add gatsby-source-filesystem

Depending on the privacy setting of the machine, use of sudo might not be necessary.

Step 2: Add & Configure the Plugin

Add the gatsby-source-filesystem plugin into the gatsby-config.js file and configure it as shown below:

// gatsby-config.js
module.exports = {
  siteMetadata: {
  // ..
  },
  plugins: [
  //add source plugin
  {
     resolve: `gatsby-source-filesystem`,
     options: {
       name: `src`,
       path: `${__dirname}/src/`,
     },
   },
  // add other plugins
  ],
  }
Step 3: Explore GraphQL Query in the Browser

Restart the development server and open up the browser and explore GraphQL at localhost:8000/___graphql .

Figure: Screenshot showing allFile added by the gatsby-source-filesystem plugin & basic GraphQl query (left panel) & queried data output (right panel).

In the screenshot above, the allFile in the left panel was available through gatsby-source-filesystem plugin. Next, play around and make a simple query as shown above and run the query which shows available data from from /src folder on the right panel.

The Gatsby source plugins bring data into Gatsby’s site from various external sources. Next we will use the above GraphlQL query to build a simple page to list all the project files from /src folder in a browser, as demonstrated in the Gatsby tutorial.

Step 4: Build Page Using GraphlQL query

Using the GraphlQL query from the previous section, a React page component was built src/pages/my-files.js  as described in the Gatsby tutorial.

Figure: Screenshot of my-file.js component with appended GraphQL query (left panel) and displayed list of site’s file in the browser (right panel).

The above my-files.js the GraphlQL query created in previous section were appended in src/pages/my-files.js react page component (lines: 37-50, left panel) to print list of files in a browser (right panel).

In the example above, the gatsby-source-filesystem plugin was demonstrated to fetch data stored in project’s /src folder. However, there are many other Gatsby source plugins to fetch data from external APIs like the WordPress, Drupal, instagram, shopify, google sheets and many others.

Extending with Transformer Plugins

In the previous section, it was discussed how Gatsby source plugins can fetch data local and external resources.The data fetched by Gatsby source plugins come in different file formats and the Gatsby transformer plugins transform those raw data into Gatsby’s data system to be able use in Gatsby sites. For example, file written in popular markdown format to create posts in Gatsby can be transformed with gatsby-transformer-remark plugin which transforms yaml markdown files into HTML suitable to display in a browser. Likewise, gatsby-source-wordpress plugin fetch data from WordPress REST API and make available to use in Gatsby sites.

In this section, we will discuss how gatsby-transformer-remark plugin & GraphQL is used to transform markdown files from /src folder into HTML to display posts in our Gatsby site as explained in Gatsby tutorial.

Step 1: Create Posts with Markdown syntax

Few dummy posts are created in src/posts/ folder in markdown format as shown below.

---
title: Hello World From Gatsby
date: "2019-7-11"
author: Mary Jones
---

This is is my second test gatsby post. It should be written in markdown.
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod 
tempor incididunt ut labore et dolore magna aliqua.
Ut enim ad minim veniam, quis nostrud exercitation ullamco 
laboris nisi ut aliquip ex ea commodo consequat.

### Image Link from Unsplash
 <img src="https://source.unsplash.com/600x300/?dog" alt="" />

Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris 
nisi ut aliquip ex ea commodo consequat.

Additional information on markdown files: Basic Syntax | Markdown Guide

Step 2:Add gatsby-transforer-remark plugin

Add gatsby-transforer-remark plugin and configure in gatsby-config.js file at the root of the project folder.

#! install plugin npm
npm install --save gatsby-transformer-remark
#! install with yarn
yarn add gatsby-transformer-remark

Next add the plugin to gatsby-config.js file, just below (lines: 15-23) and configure as as shown below.

// gatsby-config.js
module.exports = {
  siteMetadata: {
  // ..
  },
  plugins: [
  //add source plugin
  {
     resolve: `gatsby-source-filesystem`,
     options: {
       name: `src`,
       path: `${__dirname}/src/`,
     },
   },
  // add transformer plugins
  `gatsby-transformer-remark`,
    {
      resolve: `gatsby-source-filesystem`,
      options: {
        name: `posts`,
        path: `${__dirname}/src/posts/`,
      },
    },
  ],
}

In the examples above, the resolve & options section (lines: 17-23) can be omitted too.

Step 3: View GraphQL Query in the Browser

Start the development server and open up the browser and explore GraphQL at localhost:8000/___graphql .

Figure: Screenshot showing allMardownRemark, frontmatter & nodes object added by gatsby-transformer-remark plugin (left-panel), an example query of allMarkdownRemark node (middle-panel) and queried data output (right-panel).

In the example above, the allMarkdownremark (left panel, above) and markdownRemark (not visible) are added by the gatsby-tranformer-remark plugin and available for markdownRemark node query. As done previously with source plugin (above) some basic query were made (middle panel) to display title, date, author from markdownRemark node (right panel).

Step 4: Create a list of Markdown files in src/posts/ folder

For creating a list of posts (in mardown format) and displaying them in the front (home) page of our site, the codes in src/pages/index.js component requires refactoring (as shown below) by mapping markdownRemark nodes (line 13, left panel) followed by listing content below (lines: 14-19). The component is then appended with the Graphql query (lines: 26-42). The list of three markdown posts is listed, as expected, in the home page (right panel, below).

Figure: Screenshot showing use of GraphQL query to create a page to list markdown files (left panel) and displayed browser output (right panel).

The above list of markdown posts in the front (home) page of project site looks great with title, date and excerpt display but there is further work to do. This does not allow to view the entire post content nor there is link to individual post. To view separate pages for each blog post, we need to create new post components to query each post individually. That’s is a hassle! but new pages can be created programmatically with Gatsby’s Node createPages API.

Wrapping Up

In this learning-note post, we only scratched the use of Gatsby source & transformer plugins together with GraphQL query to create simple page components. In the next learning-note post, how Gatsby could programmatically create pages from Gatsby data by mapping GraphQL query results using Node createPages API will be discussed.

Next: Learning to Programmatically Create Pages in Gatsby

Useful resources

While preparing this post, I have referred the following references extensively. Please to refer original posts for more detailed information.