Gatsby is a static site generator that is built with React.js, Webpack, and GraphQL. It is used for building very fast websites that have relatively static content, for example, blogs, eCommerce websites, and even company websites.
Note: A static site generator is a platform that allows you to get all requests made in static HTML without bothering about server and template (code) interactions every time a user makes a request .
How Gatsby works.
Here is a quick overview of what we will be looking at in this post:
Before we go any further, this article assumes the following:
The file structure would look something like this after following all the steps below :
The simple-gatsby-theme
directory is our project’s folder. The packages directory holds a folder whose name is the theme we are going to create, and in that folder, we have our theme files. Lastly, the site directory contains our Gatsby site which makes use of our theme as we develop it.
A theme is different from a starter in the sense that you can build a theme as a library. It then becomes a package that can be updated and can allow you to get things up and running faster by hiding complexity. So by building a theme, we allow users who import that theme to take some inspiration from the theme and set up a user interface faster.
Setting up the project configurations
$ mkdir simple-gatsby-theme
Then run npm init
to set up the package.json
:
2. In the package.json
created, we can add a workspace that would allow us to manage the theme’s updates from the user’s end and we also added a “packages/*” that would help us link our Gatsby theme to this end user workspace theme management package:
{ "private": true, "name": "simple-gatsby-theme", "version": "1.0.0", "workspace": [ "site", "packages/*" ] }
package.json
with the yarn init
bash command:4. Next, let’s head over to the site director and run $ yarn workspace simple-site add gatsby
. This adds Gatsby as a dependency for our project using the workspaces feature of Yarn.
Note: The command above points to the package.json name “simple-site” in the site directory.
{ "name": "simple-site", "version": "0.0.1", "description": "A simple site built for a Gatsby Theme ", "main": "gatsby-config.js", "license": "MIT", "private": true, "scripts": { "develop": "gastby develop", "build": "gatsby build" }, "dependencies": { "gatsby": "^2.1.19", "simple-theme":"*" } }
We would have to add the configurations of the theme manually as a dependency for the project so that it can access the theme: "[THEME NAME]" : "*"
The first thing we have to do in our theme directory is to install Gatsby, as a dev dependency by running $ yarn workspace simple-site add gatsby -D
, our package.json
now looks like this:
{ "name": "simple-theme", "version": "0.0.1", "description": "A Simple gatsby theme", "main": "index.js", "license": "MIT", "devDependencies": { "gatsby": "^2.1.19", "react": "^16.8.3", "react-dom": "^16.8.3" }, "peerDependencies": { "gatsby": "^2.1.19", "react": "^16.8.3", "react-dom": "^16.8.3" } }
Here we have a peer dependency and a dev dependency set so that if a user installs the theme, it makes sure that Gatsby is installed. It will warn them if they don’t already have Gatsby installed. We also installed React and react-dom to the theme by running $ yarn workspace simple-theme react react-dom -D
.
We’d be using .mdx extension while working with Gatsby because it lets you write JSX embedded inside markdown. That’s a great combination because it allows you to use markdown’s syntax (such as `# heading`) for the little things and JSX for more advanced components. Plus MDX has no run time, all compilation occurs during the build stage.
This would work fine on a Mac:
$ yarn workspace simple-theme add gatsby-mdx @mdx-js/mdx @mdx-js/tag
For a windows device, run this (I will explain why later in a section below):
$ yarn workspace simple-theme add [email protected]
Since Gatsby, by default, will only look at the src/pages/index.mdx directory for the site information, our first move is to create this directory in our theme folder. Also, remember to create an index.js in the theme directory.
We will start by creating a gatsby-config.js
file in the theme directory and input the following:
module.exports= { plugins : [ { resolve : 'gatsby-mdx', options:{} }, { resolve : 'gatsby-plugin-page-creator', options:{ path: ${__dirname}/src/pages, } } ] }
We installed the gastby-content-page-creator plugin so that when the theme is built, it also looks in the src/pages/index.mdx
of the theme by reading from our package. That makes sure that when we run the code, it reads from our package because, by default, it looks at the pages in the site directory. So if we want it to load the pages from the theme, we would run the following in bash:
$ yarn workspace simple-theme add gatsby-plugin-page-creator
Here we specify that we are using a theme:
module.exports = { __experimentalThemes : [ 'simple-theme' ] };
Note: A quick hack to check if your site actually has the theme as a dependency would be to run $ yarn workspace info
From the above, we can see that the simple-site has simple-theme as a dependency meaning they are linked and we are good to go.
Then we run the demo to test by running $ yarn workspace simple-site develop
we should have this displayed on the screen:
We can use gatsby MDX layouts to target the actual layouts we want to be displayed. We’d start by creating a components directory in the src of the site and a layout.js component in which we’d have a simple react component:
import React from 'react' export default ({children}) => ( <section style = {{ display: 'block', maxWidth : '650px', margin: '2rem auto' }}> {children} </section> );
For the above code to be usable in the simple-theme, we’d have to tell MDX to resolve this layout:
module.exports = { plugins : [ { resolve : 'gatsby-mdx', options:{ defaultLayouts:{ default: require.resolve('./src/components/layout.js') } } } ] }
So by default, MDX looks for the layout.js
and implements the styles to the entire MDX.
We can write regular .mdx in the theme directory and import React components for styling these components like so:
First, we create an info.js
file and import React and some costume styling:
import React from 'react' const Info = ({children}) =>{ return( <div style = {{ padding: "1rem", backgroundColor: "blue" }} > {children} </div> ); } export default Info
Then we head over to our info.mdx
and import the component as we would in regular React:
import Info from "./../components/info" <Info> My name is obinna welcome to my simple theme </Info>
We should have a display with a blue background indicating the part wrapped around the info tag:
export {default as Info} from './src/components/info' export {default as color} from './src/tokens/color'
The whole aim of building the theme is to be able to use its properties in the site. So now, we are going to create some pages in our site and import the layouts of the theme to style in these steps:
1. Create a src/pages/info.mdx
directory
2. Export the Info component from the simple-theme’s index.js
export {default as Info} from './src/components/info'
3. Import into the info.mdx
in the site directory
And there you have it, we are using components from our theme.
Let’s say we have some theme custom styling, we want to be identified with our theme by default and we also want to give the user the ability to override these stylings. We can create a token directory in the theme under which we have our default color configuration:
export default { primary : 'blue' }
To import the styling to the index.js
component, we refactored the component to implement the import:
import React from 'react' import color from '../tokens/color'; const Info = ({children}) =>{ return( <div style = {{ padding: "1rem", backgroundColor: color.primary }} > {children} </div> ); } export default Info
This concept allows us to be able to modify parts of the theme to our taste, we can do this by creating a local file (named after the theme in use) to be picked up on render in our site directory. By doing so, any file we put in the folder will take precedence over the theme default.
src
of siteexport default { primary: 'brown' };
Therefore we now have a page rendering text with the part wrapped around the info text as brown.
We can even override components from the site. First, we would have to create the same identical component folder in our site directory. Let’s name it simple-theme/components/info.js
.
Note: To access the custom components to be modified we’d have to export from the index.js of the theme
export {default as Info} from './src/components/info' export {default as color} from './src/tokens/color'
Our index.js
becomes :
import React from 'react' import {color} from 'simple-theme' const Info = ({children}) =>{ return( <div style = {{ padding: "10rem", background : color.primary, fontSize : '30px' }} > {children} </div> ); } export default Info
So previously, I mentioned that we can use more than one theme; thus, we will set up a child theme that is also dependent on the simple-theme. I will call mine “bat-theme”, here we initialize yarn by running yarn init
and set up the package.json
with the required theme dependencies.
{ "name": "bat-theme", "version": "0.0.1", "main": "index.js", "dependencies": { "gatsby-plugin-page-creator": "^2.0.9", "simple-theme": "*" }, "devDependencies": { "gatsby": "^2.1.19", "react": "^16.8.3", "react-dom": "^16.8.3" }, "peerDependencies": { "gatsby": "^2.1.19", "react": "^16.8.3", "react-dom": "^16.8.3" }, "license": "MIT" }
We added the simple-theme to be a dependency of the bat-theme because we want it to be connected to the parent theme, so even when the user installs bat-theme they can access the simple-theme features.
Then we can create a gatsby-config.js to import the parent theme into the child the same way we connected to the site and resolve the package.json in the index.js:
module.exports = { __experimentalThemes:[‘simple-theme’] };
We can test that the child theme is working by modifying the gatsby-config.js
and package.json
of the site to use the bat-cave theme which is linked to the simple-theme. To check how this is all interacting we run yarn workspaces info
and we should have this displayed:
We can see that the bat-theme is dependent on the simple -theme which the site is dependent on.
While preparing this article I ran into some errors:
Things we should look forward to from Gatsby theme:
I really enjoyed explaining how Gatsby themes work. One of the many advantages of themes is that you can install multiple themes at once to your project. You could also build a lot of themes to help improve workflow for other developers.
The most exciting part of building the theme was writing the MDX, it really lives up to the hype. I hope to build some themes with Gatsby and I hope you do too 🙂 If this interests you, may I suggest watching the full video by Jason and John. Here is a link to the repo for this article. Happy coding!
Install LogRocket via npm or script tag. LogRocket.init()
must be called client-side, not
server-side
$ npm i --save logrocket // Code: import LogRocket from 'logrocket'; LogRocket.init('app/id');
// Add to your HTML: <script src="https://cdn.lr-ingest.com/LogRocket.min.js"></script> <script>window.LogRocket && window.LogRocket.init('app/id');</script>
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowBuild scalable admin dashboards with Filament and Laravel using Form Builder, Notifications, and Actions for clean, interactive panels.
Break down the parts of a URL and explore APIs for working with them in JavaScript, parsing them, building query strings, checking their validity, etc.
In this guide, explore lazy loading and error loading as two techniques for fetching data in React apps.
Deno is a popular JavaScript runtime, and it recently launched version 2.0 with several new features, bug fixes, and improvements […]