We have setup our project but it doesn't do much right now. Lets add a backend to store our products!
This is part 2 in a series of tutorials. The format is step by step.
So lets recap what we have done so far:
Having a website that looks sweet is all well and good but we are going to need somewhere to store and our products data. We could do it from the filesystem but thats not very user friendly. What if we could not only store our products data somewhere, but we could also give the user of our theme a nice UI from which to enter their data..... Enter Sanity.io 💃
Sanity will allow us easily (and i really mean easily 😉) set up our backend with a React based dashboard. The schema is super easy to get the hang of. Lets get started!
At our project root create a new folder called studio. Navigate into that folder and install the sanity CLI then initialize the sanity project.
This will globally install the CLI and create a new project for us. You can follow the step provided by the CLI, choose the ecommerce template and for the rest you can accept the defaults.
I have noticed some lag when running sanity init via the in built vscode terminal, it can hang. If it does i recommend quitting and running the command from another terminal. I use Cmder.
Once installed open the studio folder and you will see some schema definition files. Open the product.js file. It should look like this:
Each object in the fields array corresponds to an input field in the studio, you can see the type the field expects with the type key. For some they refer to other objects which themselves define their own input fields. For example the Default variant object field. For more information of the inner workings of sanity i highly suggest you go over their docs. They are really exceptional. For now we can leave this file as is.
After you have had a little explore of the different schema files and read the docs on the sanity site create a new file in the schemas folder and call it home.js. We will use this to allow the theme user to add a hero image to the home page of our theme. Add the following to the new home.js schema file:
The title field will be the name of our website. You can auto generate the slug in the studio. The images array will allow us to add multiple images which we will be able to access via a graphql query on our home page, page. Wait till you check out the image handling in the studio 👯♀️
We can also create our blog post schema. You'll notice that this time we have added a description to each field object. This will show in the studio as helper text to explain to the user what they should do or what the input expects. Its a small but important feature when thinking about studio handover, in our case, the end user of our theme.
Blog Post Schema
Next open the schema.js file located in the same folder and inside the createSchema builder we can add our home and blog schemas, make sure you import it if vscode doesn't automatically do this for you. By default the function is well commented.
Now that we have created our new home page and blog schemas and exported them in the builder function we can deploy and start our studio!
When deploying we can host our studio anywhere we like but sanity can also handle this for us. If we make a change to our schema we have to remember to run sanity graphql deploy for the changes to take affect. You should now be able to view the studio at gatsby-theme-fashion.sanity.studio. On the left of the studio you will see all of our content, the stuff created from the schema definitions. Click on the product and then click to create a new product. Now you should be able to see how each of the field type are represented in the studio. The default variant box is where we will be getting most of our data from. Feel free add some products, filling in the necessary information. As we chose the ecommerce template there will already be some products you can use for reference. I would suggest looking over them and adding your own. Once done remove the default template products.
Open the home content tab on the left and add an image to be displayed on the home page of our theme. Make sure you remember to hit publish every time you add or change something in the studio otherwise nothing will happen 😆. If you open the blog content tab and scroll down you will see what looks like a wysiwyg editor. This is sanities rich text editor. In order to properly display its contents in our theme we will need to install another package.
This will render an array of block text from the rich text editor in our studio. Each paragraph will be an index in the array. Now in order to use this component and display our rich text properly we will have to create some serializers. This concept was hard for me to understand at first and i did do some hacky stuff to get it working. The actual way of doing it, once you get it right is very simple. There is a handy blog post about it by Eric Howey - using-theme-ui-with-sanity that gives an example of using the serializers with theme-ui, we'll be using the sx prop directly instead of importing the theme-ui Styled component but it will work much the same way. Lets create a folder under components and name it common. Inside create a file called index.js and add the following:
We are styling the html elements that are specified in the rich text editor in our studio with the theme-ui sx prop, getting the values from our theme file. Pretty nifty. For a more in depth look into how it works check out the sanity.io docs. Of course you can add all the html elements your heart desires so long as they are already defined in the schema for block content. In fact, lets take a peek at that file so that you know what i mean:
This is taken directly from the template project output. You should have the same in your sanity project under the schemas folder. As you can see the blocks array defines the markup we want to use in our rich text editor, these are the defaults, you can add or remove as many as you wish. Again, see the docs for more info 😊
So lets recap what we have done so far:
We're making great headway! Now that we have our sanity backend up and running we need to hook it up to our theme. Head over to the theme projects root and install the gatsby-source-sanity plugin.
Now create two .env files at the demo sites root. .env.development and .env.production. In these files add the following:
If you go to https://manage.sanity.io/ and click on your project, gatsby-theme-fashion, or whatever you chose to name it you will find your project id below the project name. You can find the dataset name if you have forgotten what you called it (it will be production if you went with the defaults) under the datasets tab directly under the project id and studio link.
Lets tell our theme to expect these variables form the consumer. Open the themes gatsby-config.js file and add the following:
Theme - gatsby-config.js
Now we want to navigate to our gatsby-config.js file in our demo sites folder and add the following:
Here we are checking what environment we are in and getting the env variables dependant on that. We will just add the same data to both the development and production env files but you can create different ones dependant on your needs. Its important to always keep your API keys and other sensitive information hidden so the go to thing to do is use env variables.
Now that we have configured our theme to use our sanity backend we can start creating some components to fetch the data and display it. We'll start with the home page. As of now all we have to display is our hero image we added to our home content in the studio. Create a folder under components and call it home. Inside create a new file and call it hero.js.
Lets break it down.
This component is now ready to be imported into our index.js file that is waiting for us all lonley in the pages folder of our theme. Right now it looks like this:
Lets remove all that and add our hero image!
By importing the Main component and using it as the parent to all others in this component we have told gatsby that anything inside this component will live in the grid area main. This will be the pattern moving forward for all of our pages.
Go to the demo project and run yarn dev to see your image displayed. Lets take a look at our content plan again and check off what we have done:
We've still got some way to go 😅 The showcase and blog post snippets both require us to do some setup before we can add them to the home page. So lets go ahead and create the about, contact and instagram feed sections!
We can begin by adding a container div to our home page component (index.js) and styling it with our trusty friend the grid.
Seeing as our home page sections are all going to be the same we can extract that to a new component. Create a new home-section.js file under the components/home folder.
We can now import and use that component to wrap our placeholder sections in our home page.
Our about section will simply display some text that we will import via a graphql query form our sanity backend. First we need to create the schema for that. Head into the sanity project and create a new schema file under the schema folder and call it about.js
Import it into the schema file and deploy. Then add some content.
Now we can use the sanity block-content-to-react package and our sanitizers. Create an about-section.js file under components/home
Lets add our new about component to our home page:
Next up is our instagram feed. For this we will be using a great theme by Horacio Herrera called @horacioh/gatsby-theme-instagram. Its super simple to use and gives great results. Just what we need! From our themes root run then navigate to the themes gatsby-config.js and add it there.
Theme - gatsby-config.js
Now we can add it to our home page. There are number of options for how to display the data, i suggest checking out the package docs, we will be using the grid with that standard styling.
So lets recap what we have done so far:
😅 Wow, we have accomplished a lot! I think this is a good place to stop and reflect on what we have done so far. In the next part we will be diving into gatsby-node.js and creating pages from queries on the fly using some templates that we will create. 😎