This guide is specifically for Gatsby websites using gatsby-source-sanity, linked to a repository.

Other source plugins may have similar 'watch mode' functions, and could likely apply the same thinking.

Gatsby Cloud is amazing. Live preview and insanely fast builds with almost no config. It's also \$99US/month. Any big business using Gatsby should absolutely consider using it.

But JAM Stack sites draw a lot of hobbyist, personal and small business websites. For these it's a bit steep.

Luckily we can roll our own live preview for Sanity powered websites using Heroku.

Get preview working locally first

The Sanity Source plugin for Gatsby has a watchMode feature. See the plugin's guide for details.

When it's working:

  • Your gatsby-config.js looks something like the below
  • watchMode and overlayDrafts are enabled so long as you're not a production environment
  • The Sanity API read token is stored in your local .env.development file
  • When you make edits in Sanity, you're seeing them update live in Gatsby, on your local development environment
const isProd = process.env.NODE_ENV === "production";

// ...

module.exports = {
  plugins: [
    // ...other plugins
      resolve: `gatsby-source-sanity`,
      options: {
        projectId: process.env.SANITY_ID,
        dataset: `whateverYouCalledYourDataset`,
        overlayDrafts: !isProd,
        watchMode: !isProd,
        token: process.env.SANITY_TOKEN

All good? Let's go on.


This all works by running Gatsby in development on a live server, as if it were your local environment.

You'll need a Heroku account, and the Heroku CLI installed.

By default a Node JS app on Heroku will look for a "Procfile" to start, and if not specified, will look to run a default script from your package.json.

Here's my start script:

"scripts": {
  "start": "gatsby clean && gatsby develop -H",
  // ...other scripts

(-H gives you a network address during development which is super handy!)


  1. Get your start script in order
  2. Create a new App in the Heroku dashboard
  3. Link your Gatsby site's repository with the Heroku app using the CLI, there should be an example command for existing repository something like heroku git:remote -a app-name
  4. Go to Settings > Config Vars and add your environment variables, most importantly your Sanity API read token. This can be the same one you use locally
  5. Run heroku config:set NODE_ENV=development to make the Heroku App run in development, so watchMode is enabled
  6. Deploy! git push heroku master

The first time you navigate to the URL of your Heroku app, it may take a few moments to come online. It's doing the same Gatsby develop command you do locally.

Once you can start browsing the Gatsby website, try making edits in Sanity. You should see them updating in real time, no matter whether you're working from your local development version of Sanity Studio or your deployed/hosted version.


Get your preview into Sanity

With Sanity it's possible to setup a Production Preview URL for your content editors. Which will open the currently edited document in a new window.

However an even nicer implementation is to include a Preview Pane right inside Sanity.

With either implementation it's best to use your local preview where possible, instead of spinning up the Heroku app needlessly during development.

We use the function below for both the Production Preview and Preview Pane iframe.

const remoteURL = "";
const localURL = "http://localhost:8000";
const previewURL = window.location.hostname === "localhost" ? localURL : remoteURL;

export default function resolveProductionUrl(document) {
  return `${previewURL}/${document.slug.current}`;

Make sure your Heroku app isn't indexed

Finally you may want to also ensure your Heroku app isn't being indexed by using something like gatsby-plugin-robots-txt.

It has an inbuilt option to produce allow/disallow versions depending on the environment.


Since Gatsby sites can be setup in a near infinite number of ways, perhaps the above didn't work for you. Reach out for help.

Thanks to Knut for nudging me in this direction.