As many of you know, we love gatsby a lot at truesight and we are using it for our main site as well. Most of the content on the site is pretty static and we have to go back to code to edit anything. say hero title, hero description, client images, etc. Wouldnt be awesome if we could edit everything without touching code? Well, my friend, you are about to see something awesome now 😎
Sanity.io is a headless CMS that content editors can use to edit and publish content. So in this post, I'll share how to setup sanity and use it in gatsby project.
We will require to install sanity CLI to set up the sanity project. Here is the simple command to install it:
npm install --global @sanity/cli
sanity init
This command will ask to log in sanity, create a project, or use an existing one, create a dataset, and select a project template.
To start the development server for Sanity Studio, run this command in your sanity project folder:
sanity start
This builds the initial JavaScript code required to run the studio and starts a local development web server. As you modify and save the code, the server will automatically rebuild the studio and refresh the browser.
The studio is just an HTML file and some JavaScript bundles that run in your browser. It talks to the Sanity API which stores your data and lets you query it from whatever platform or front-end you want.
Now let's create a schema for our site.
Schemas are basically blueprints of your content. They define the fields we will for the dashboard. For this tutorial, we will create a two custom schema called siteSettings
which will set the basic settings of the site like Hero Title, Hero Description.
Now at schemas/schema.js
, you will see:
import createSchema from "part:@sanity/base/schema-creator"
import schemaTypes from "all:part:@sanity/base/schema-type"
export default createSchema({
name: "default",
types: schemaTypes.concat([
/* Your types here! */
]),
})
Now let's add siteSettings schema to it. First, create siteSettings.js
// /schemas/documents/siteSettings
export default {
name: "siteSettings",
type: "document",
title: "Site Settings",
__experimental_actions: ["update", /* 'create', 'delete', */ "publish"],
fields: [
{
name: "heroTitle",
type: "string",
title: "Hero Title",
},
{
name: "heroDescription",
type: "string",
title: "Hero Description",
},
],
}
Add the siteSettings to the list of our schemas.
// /schemas/schema.js
import createSchema from "part:@sanity/base/schema-creator"
import schemaTypes from "all:part:@sanity/base/schema-type"
import siteSettings from "./documents/siteSettings"
export default createSchema({
name: "default",
types: schemaTypes.concat([
siteSettings, ]),
})
Now if you load sanity studio in our browser at localhost:333/desk, you will see our siteSetting document there. But there seems to be a problem with it, we can't create any document from it. It's because of the __experimental_actions
in schema file. We only want it to have single document of siteSettings. But to make it work, we will need to make some changes to our sanity dashboard.
Documents type which can only have a single document are called 'one-off' documents in sanity. We will need to tell this to sanity that siteSettings
is one-off document. To do so, we will need to modify sanity desk structure ( Sanity Dashboard is called Desk ). Let's do it.
Create a file called deskStructure.js
at root and paste following code in it:
// deskStructure.js
import { GoSettings } from "react-icons/lib/go"
import S from "@sanity/desk-tool/structure-builder"
const hiddenDocTypes = listItem => !["siteSettings"].includes(listItem.getId())
export default () =>
S.list()
.title("Content")
.items([
S.documentListItem()
.schemaType("siteSettings")
.title("Site settings")
.icon(GoSettings)
.child(
S.document()
.schemaType("siteSettings")
.documentId("siteSettings")
.views([S.view.form()])
),
...S.documentTypeListItems().filter(hiddenDocTypes),
])
Now, in your sanity.json
file, pass the file path to tell sanity we will be modifying desk structure.
// sanity.json
{
...
"parts": [
{
"name": "part:@sanity/base/schema",
"path": "./schemas/schema"
},
{ "name": "part:@sanity/desk-tool/structure", "path": "./deskStructure" } ]
}
Now restart your server and you should be seeing something like this:
siteSettings
.That's all we needed to do on the sanity side. Let's load this data in gatsby.
Lucky for us, there exists a gatsby plugin (https://github.com/sanity-io/gatsby-source-sanity) to connect gatsby to sanity.
Let's add the this plugin
yarn add gatsby-source-sanity
Before adding this plugin to gatsby, make sure you create a read token from sanity ( https://manage.sanity.io/ ) for your project.
After you have created the token, in your gatsby-config.js, add the following code:
module.exports = {
// ...
plugins: [
{
resolve: `gatsby-source-sanity`,
options: {
projectId: `<your-project-id>`,
dataset: `<your-dataset-name>`,
token: `<your-sanity-read-token>`, // you can also use it from env variable
},
},
// ...
],
// ...
}
Make sure to replace the variables with correct values and restart the server.
Now let's call our sanity data in gatsby. In our pages/index.js
file, add the following graphql query.
import React from "react"
import { graphql } from "gatsby"
export const query = graphql`
query FrontpageQuery {
site: sanitySiteSettings(_id: { regex: "/(drafts.|)siteSettings/" }) {
heroTitle
heroDescription
}
}
`
const IndexPage = props => {
const { data, errors } = props
if (errors) {
// you can handle errors here.
}
const heroTitle = site.heroTitle
const heroDescription = site.heroDescription
return (
<div>
<h1>{heroTitle}</h1>
<h3>{heroDescription}</h3>
</div>
)
}
export default IndexPage
gatsby-source-sanity
plugin, we have access to every data in sanity data. To fetch data from sanity, we can simple add graphql query now in our pages like we have done with FrontpageQuery
.That's it for this tutorial, we will be adding more tutorial sanity very soon 😃 Stay tuned.