Blazing fast development with Gatsby and Sanity.io (ssr)

Written by Knut Melvær

Missing Image!

We would prefer everything to be real-time. So we built the Sanity studio and backend from the ground up to enable real-time collaboration, and made sure there were real time-client APIs from day one. We always wanted Sanity front-ends to also reflect content changes in real-time, we just didn't know of a cost effective way to accomplish this for everyday needs.

Then someone showed us Gatsby Preview. A general way to get real-time preview that did not involve a great deal of custom plumbing! Our new Sanity Gatsby Source Plugin uses the Sanity real-time API to instantly rebuild when content changes. When developing this means a group of people can freely work together on content models, UI design and the content itself. In real-time. Without rebuilds. It feels great!

You can experience it with the example company website we built for this launch. We ship it in a monorepo along with a Sanity project that has models for things like case studies and blogging. It's pretty minimal to make it easier to extend.

The box contains:

A company website built with Gatsby

Sanity Studio with schemas for

PortableText [components.type] is missing "callToAction"

Watch a walk-through of setting it up:

About the Gatsby Source Plugin for Sanity

You add the source plugin to your Gatsby project

with npm i gatsby-source-sanity, and explore the configuration options in the GitHub repo:

PortableText [components.type] is missing "callToAction"

Minimal Configuration

Gatsby provides one of the easiest ways to create a React front-end for your Sanity.io project. The source plugin gives you a comprehensive GraphQL API in Gatsby to all your content – right out of the box. We strongly recommend using the GraphiQL explorer to test queries and get familiar with the schema documentation. It's super useful!

To get started with the Gatsby source plugin, install it in your Gatsby project:

yarn add gatsby-source-sanity# or npm install gatsby-source-sanity --save

Once installed, add this configuration to gatsby-config.js:

require('dotenv').config()

module.exports = {
  plugins: [
    'gatsby-plugin-postcss',
    'gatsby-plugin-react-helmet',
    {
      resolve: 'gatsby-source-sanity',
      options: {
        projectId: '<yourProjectId>',
        dataset: '<yourDatasetName>',
        // To enable preview of drafts, copy .env-example into .env,
        // and add a token with read permissions
        token: process.env.SANITY_TOKEN,
        watchMode: true,
        overlayDrafts: true
      }
    }
  ]
}

If you start Gatsby in developer mode (npm run dev or yarn dev) you can query your content from the Sanity content API using GraphiQL located at http://localhost:8000/___graphql.

Preview content changes with watch mode

Two persons on laptops editing a website

Static site generators have benefits in terms of a fast end-user experience. Yet a trade-off is that the site needs to rebuild every time you make edits to the code or the content. Gatsby has already solved the development aspect of this by doing hot module replacement when code is changed – but this doesn't include updated content that's been made available through APIs.

When watchMode: true in the plugin configuration, the Sanity source plugin will set up a listener and inject any changes. If you add additionally add a token with reading permissions and set overlayDrafts: true, you will get all editing changes live. Besides being from the future, this also makes it tenable for a team to collaborate on design, code, and content at the same time, across multiple devices.

Fast, yet frugal builds

The source plugin uses Sanity.io’s export API and it streams all your documents in one go. It's not only very fast, it's also just one API request for all the content – with a single additional request for the schema when you build. Independently of document number of size. This means that you can build your Gatsby site thousands of times each month on the free developer plan (you can add your card to the dev plan for an affordable pay-as-you-go option should you happen to blow past the generous base quotas).

No accidentally missing fields or types

Most source plugins generate a GraphQL schema inferred from whatever content is available at any given moment. This means that types and fields can be missing if the content is present or not. This can get a bit cumbersome to work with, and doesn't encourage a more controlled way of planning your content models.

If you deploy a GraphQL API for your Sanity project (sanity graphql deployΒ in your project folder), the plugin will automatically fetch the schema definition to make sure that all your types and fields are present.

The schema definition prevents your site from accidentally breaking if you delete a document which had the last occurrence of content for a given field. As far as we know, no other source plugin solves this problem right now, but it should be noted that there's some awesome work being done in the Gatsby community to provide an official and better solution for this down the road.

The Power of Portable Text

While we understand the appeal of Markdown (react-markdown is the child of one of our lead developers), it comes with limitations. Even cool permutations like MDX and processors like remarked have some important constraints when it comes to how easy it is to sustain and reuse that content across projects.

That's why with Sanity.io, rich text content is stored as Portable Text, deeply typed and highly structured. Not only does this enable you to offer a WYSIWYG experience for yourself and your authors without all the bloody mess, but you also can get rid of dangerouslyInsertInnerHTML in your Gatsby templates, and have total and effortless control of how different parts of your rich text content should be rendered. We provide you with a handy library for React that takes care of the default HTML and lets you override whatever parts of the text content with your own React components.

{/*
So instead of this:
<div dangerouslySetInnerHTML={{__html: post.html}} />
You can do this:
*/}
<PortableText
  serializers={{
    types: {
      code: ({node}) => (
       <pre data-language={node.language}>
          <code>{node.code}</code>
       </pre>
     )
    }
  }}
  blocks={post._bodyRaw}
/>

Full gatsby-image support

Close up of Sanity Studio with hotspot editing

Sanity already comes with a capable and easy to use image pipeline on a superfast CDN with transforms on demand, but if you want to use the same frontend components with a mix of remote or local sources or prefer the functionality of the gatsby-image library, we have made it easy for you to leverage that. Additionally, you'll have access to all that handy image metadata, like aspect ratios, dimensions, color palettes, the optional EXIF data and geotags via the API.

Sanity.io + Gatsby.js = Perfect JAMstack companions

Gatsby has already set some high standards for developer experience by striking the nice balance between code and configuration. We have worked hard to make it as nice and effortless as possible to use Sanity.io as a content backend with Gatsby, and we hope that you will enjoy building websites with this combo.

If you quickly want to get started with a full JAMstack combo, check out the company website example we put up. It features both a Studo configuration and a website template with projects, blog, people, and pages. You should be up in minutes.

We're very excited to see whatever you do with it and welcome you to come with all your questions, feedback, and ideas in our developer community.

A side by side view of a schema, a Gatsby front-end and the Sanity Studio