We're going to go from start to finish and create a gatsby theme that you can deploy as an npm package. In the first part we will cover the base setup of the project.
This is part 1 in a series of tutorials. The format is step by step.
So where to start? You have an idea, you want to create an ecommerce theme for all the world to use. In this tutorial we are going to create a new gatsby theme from scratch, handle payments using snipcart, store our data with sanity.io and style it with theme-ui. Its going to be dope 😎
There are a few pre-requisits, Im going to assume you know how to use Gatsby and React to a certain degree, the rest we will walk through.
We are going to be building this from scratch so lets start by creating our new project
Cool beans, so lets now create our project. When working with gatsby themes i like to use yarn workspaces, this allows us to keep our theme and an example site in a monorepo with yarn controlling the dependencies between them. Lets create our projects root, we'll use the -y flag to auto fill the package.json stuff as we will be removing it all anyway.
Now that we have a package.json in our folder we can open our code editor and remove the auto filled stuff and add our own. We want to add the workspaces key and add our project folders. There are many ways of doing this and people have different opinions about which way is best. This is my preferred method.
We want the project to be private as we wont publish it and also workspaces wont work if we don't set this. We have also specified that we will have one folder for our demo project and another which will hold our packages, or our theme(s).
Create the demo and packages folders
We'll start with our theme and hop over to the demo site a bit later on. Lets move into the packages folder and create our themes folder and initialize the project, following yarns instructions for setup as we go. I like to set the version to 0.0.1 from the start as during development we will be publish our package and when it comes time to release it in the wild its going to look strange if our version number is 54.9.7 or something. Keep it at the patches in development until release.
Now that we have our theme project installed lets add the base packages we are going to need. For us those are gatsby, react, react-dom, theme-ui, gatsby-plugin-theme-ui @emotion/core and @mdx-js/react. Lets also add prettier so that all our code looks pretty once we save it! 😇
Niiiice! Cool, now lets add some scripts to our package.json for building, cleaning and making stuff pretty.
You can give the keys whatever name makes sense to you. We'll be mostly using dev, clean and pretty. We could set up a pre commit hook to run pretty when we commit code, you can look that up, for this example we will skip it. I quite like typing out yarn pretty and watching all my code transform. You can also set it up to run on save in vscode, again, that is something for you to google.
We want to add gatsby, react and react-dom as peer dependencies so that the end user has to install them.
Now we need to add our gatsby-config.js file and add the plugins we have installed for our theme. Its important to add the gatsby-plugin-theme-ui plugin at the end as it will be overriden by the theme consumer if they have it installed also.
We have used gatsby-plugin-google-fonts so that we can easily install some nice fonts from google. Feel free to choose your own.
I should add at this point that the versions are explicit to this tutorial, everything should work regardless, that being said it can be that some breaking changes are introduced at some point in the future so yours may differ from mine, if you have any problems check the changelog from my version to the version you are using to debug the problem.
Ok so lets add some folders and files to our project.
We also want to create an index.js file at the root of out theme as thats what gatsby is looking for
Add a comment to this file so it has some content and we know whats going on. Later on we can if we like export some of our theme components from this file for the end use to import.
Sweet! We've got a really basic theme setup, it doesn't do anything right now, first we want to setup our demo site and link it to our theme. The magic of yarn workspaces!
Your demo sites package.json should look something like this:
We have added dotenv so that we can access the environment variables later on. We are also telling our demo site to use any version of our theme it finds. We have also added our scripts so that we can actually run the thing!
Next create a new file called gatsby-config.js at our demo projects root and add our theme as a plugin.
Right now we don't have any options that our theme requires so this will do. Then we run yarn from the root of our project to link it all up and we can then check if its all cool
We should see the following output indicating that our demo site is linked to our theme:
So now might be a good time to commit our work. Go to github and login to your account and create a new repository called gatsby-theme-fashion. Then from the root of our project....
WHOA there ✋ Lets think about this for a second, we have just installed a bunch of packages, which means we have a node_modules folder at our root and in each project, thats a hell of a lot of files that we do not want git to see. Lets create our gitignore file at our projects root.
Then add the following to it:
Now i'll be honest, im not sure if you need to do this but i do it anyway, lets copy that file to our theme and demo projects.
Ok, nice! Now that thats done lets initialize our project with git and commit our work. You can get your remote repository url from the repository page you created.
So lets recap what we have done so far:
Now would be a good time to add some content and check that our theme is working. Head into your theme projects index.js file located inside src/pages folders and add a generic component to display an h1 that will render from our demo site as the imported theme.
Go into your demo project and run gatsby dev. You should see a white page with the h1 text at the top left of the page, hurrah 🥳
Now that we have the base setup complete we can start thinking about what we want to have in our theme. As this is an ecommerce theme there are some basic things that we should consider before we continue. There will be a lot to add so lets get started!
These are some of the basic thing we expect an ecommerce site to have. There are of course a lot more thing we could add but lets keep it simple for our example theme. We will be keeping our layout fairly simple with a navbar at the top followed by a hero image and a section explaining about the store. Then a showcase of our top 3 most popular products followed by our Instagram feed and finishing off with our contact form in our footer.
We can begin by creating all the necessary pages:
Theme-ui will enable our end user to override some of our style with ease through shadowing our theme file which will hold all of our colours, fonts and spacings. In order to get started with adding our themeable variables we need to shadow the index.js file form the gatsby-plugin-theme-ui package in our src folder. See Theme-ui for more details.
I often start with the sites basic layout. There are a couple of ways to do this. We could create a layout component in our components folder with a css reset and import that into all or our components/pages but there is an easier way utilizing gatsby-plugin-layout.
Lets add that plugin
Then we need to add it to our gatsby-config.js file:
Create a layouts folder inside your src folder and add an index.js file. This will be our base layout for our site.
This doesn't do much apart from reset some css and render the children within it. Lets create a basic grid layout using css grid. We are going to be using the theme-ui sx prop to add styling to our elements.
First up create some grid area strings as constants to be used in our grid. You can add these to a separate file if you wish but we will be adding them to the layout file in this example.
Then we can add these to the div that wraps our returned children in the layout component.
Lets breakdown whats going on here. I used to use Emotion css plus theme-ui to design and style my components, you can read about my experience here CSS grid with Theme-ui. Basically theme-ui allows us to specify breakpoints using an array syntax, so [mobile, tablet, desktop]. Pretty cool huh! Now we need to create our nav, main and footer components. All the sites amin content will live inside the main component, by using gatsby-plugin-layout we can just import main as a wrapper to tell gatsby that whatever component should be rendered inside this grid area.
Create a layout folder inside our components folder and add these three components:
You may be wondering where the background colour is coming from... When using theme-ui we import all of our styles from one main index file. This file can be shadowed by the theme consumer and thus they can override whatever styles we have in there to change the look of the theme. Lets create that now.
Inside the src folder create a new folder called gatsby-plugin-theme-ui, inside that folder create a new file named index.js and add the following:
These values can be accessed via the sx prop as seen above.
Lets add them to our layout to complete this part of the tutorial.
So lets recap what we have done so far:
In the next part we will start adding our main content components and a backend to store our products. 😎