Gatsby Source Plugin Starter Example Breakdown
I recently published an article covering the development of a custom Gatsby Source Plugin. To help get off the ground faster I created a starter repository.
I didn’t want to include too much details in the tutorial, so I have written this article to explain the files and reasoning behind what goes into the starter repository.
Link to the repository:
Whats in the Box?
The repository contains the following files:
As Gatsby is part of the ReactJS ecosystem and modern JS makes life so much easier, Babel is an essential build tool. This file imports the babel-preset-gatsby-package which contains the default Babel setup for all Gatsby projects. The packages it includes are:
For more information see: https://github.com/gatsbyjs/gatsby/tree/master/packages/babel-preset-gatsby
A standard development file. I have included this for ease later down the line.
Always, always. always make sure your documentation is up to date. It doesn’t take too long to type up how to install and use a plugin. You don’t need to write a novel, but it helps if you know what you have built when you come back to it in 5 months.
I tend to use markdown for readme files. It is simpler than messing around with HTML, and I find a lot quicker to write!
This cheatsheet should help if you need pointers: https://www.markdownguide.org/basic-syntax
This file should always be left empty. I have a feeling it is due to being used in a build process later, but it might not be. Either way, leave this empty! If anyone knows its purpose, please let me know on Twitter @robertmars.
This contains the required packages to run a basic Gatsby source plugin. Be sure to have a dig around. The scripts section includes a build, prepare and watch command. You can use with Yarn or NPM to run these. It doesn’t really matter, but I have found with other builds that Yarn tends to be less prone to errors.
Build and watch are the same thing, but one continually watches the code for changes. These commands dump the compiled code into the root folder. The prepare command runs the build command, but with the production flag switched on. I have not included a __test folder, I will leave that decision to you.
It is essential to have Gatsby as a peer dependency, as this includes a number of internal functions that will make your life a lot easier. One of these that we will talk about later is the createContentDigest(). This stops the need for building custom functions, which makes the code a lot cleaner.
The meat of the plugin. This file is where everything begins, and (probably) ends. This is where the fun happens.
This function takes the data to be added to GraphQL and adds as a node. There are several required arguments. This are:
The function is used like this:
id: //globally unique ID
type: // unique nodetype. It is used by GraphQL so nodes can be queried
contentDigest: hashed string made from the content
// the rest of your data
Thankfully Gatsby provide some helper functions to go with the createNode function. To create unique IDs use the createNodeID function, and use the createContentDigest function for contentDigest.
The point of this function stumped me for a while, but after a little digging around in the Gatsby source I found its purpose. It takes a unique string or number as an argument and returns a UUID. The string or number should be in reference to the Node being created. An example would be:
const nodeID = createNodeID('picture-43')
If you are interested in the inner workings, it uses the plugin name as a namespace and then uses the NPM package uuidv5 to return a unique string.
To ensure Gatsby only rebuilds the graphQL structure when the data changes, each node requires a contentDigest. This is a hashed string, created from the contents of the createNode data. Simply pass the data (this can be either an object or string) to the createContentDigest function and it will return the hash.
There is nothing like a good helper file. I have included a few functions that I seem to use over and over again. These include:
- flattenArray() – Destructures an array and flattens to a string
- getCurrentTimestamp() – This makes a unix timestamp
- isArray() – Checks if an element is an array
- isObject() – Checks if an element is an object
- isObjectEmpty() – Checks if an object is empty
And That’s It…
It is fairly small, but saves a little bit of time! Feel free to send a PR and I’ll get it added if you feel this is missing anything. I am looking to make this the most helpful/least amount of bloat.
I hope this article has helped!