• Stars
    star
    195
  • Rank 199,374 (Top 4 %)
  • Language
    TypeScript
  • License
    MIT License
  • Created over 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Gatsby source plugin for building websites using Sanity.io as a backend.

gatsby-source-sanity

Gatsby source plugin for pulling data from Sanity.io into Gatsby websites. Develop with real-time preview of all content changes. Compatible with gatsby-plugin-image. Uses your project's GraphQL schema definitions to avoid accidental missing fields (no dummy-content needed).

Get up and running in minutes with a fully configured starter project:

Watch a video about the company website built with Gatsby using Sanity.io as a headless CMS

Table of contents

See the getting started video

Install

From the command line, use npm (node package manager) to install the plugin:

npm install gatsby-source-sanity gatsby-plugin-image

โš ๏ธ Warning: If using Gatsby v4, make sure you've installed version 7.1.0 or higher. The plugin has a dependency on gatsby-plugin-image which itself has dependencies. Check gatsby-plugin-image README for instructions.

In the gatsby-config.js file in the Gatsby project's root directory, add the plugin configuration inside of the plugins section:

module.exports = {
  // ...
  plugins: [
    {
      resolve: `gatsby-source-sanity`,
      options: {
        projectId: `abc123`,
        dataset: `blog`,
        // a token with read permissions is required
        // if you have a private dataset
        token: process.env.SANITY_TOKEN,

        // If the Sanity GraphQL API was deployed using `--tag <name>`,
        // use `graphqlTag` to specify the tag name. Defaults to `default`.
        graphqlTag: 'default',
      },
    },
    `gatsby-plugin-image`,
    // ...
  ],
  // ...
}

You can access projectId and dataset by executing sanity debug --secrets in the Sanity studio folder. Note that the token printed may be used for development, but is tied to your Sanity CLI login session using your personal Sanity account - make sure to keep it secure and not include it in version control! For production, you'll want to make sure you use a read token generate in the Sanity management interface.

Basic usage

At this point you should set up a GraphQL API for your Sanity dataset, if you have not done so already. This will help the plugin in knowing which types and fields exists, so you can query for them even without them being present in any current documents.

You should redeploy the GraphQL API everytime you make changes to the schema that you want to use in Gatsby by running sanity graphql deploy from within your Sanity project directory

Explore http://localhost:8000/___graphql after running gatsby develop to understand the created data and create a new query and checking available collections and fields by typing Ctrl + Space.

Options

Options Type Default Description
projectId string [required] Your Sanity project's ID
dataset string [required] The dataset to fetch from
token string Authentication token for fetching data from private datasets, or when using overlayDrafts Learn more
graphqlTag string default If the Sanity GraphQL API was deployed using --tag <name>, use this to specify the tag name.
overlayDrafts boolean false Set to true in order for drafts to replace their published version. By default, drafts will be skipped.
watchMode boolean false Set to true to keep a listener open and update with the latest changes in realtime. If you add a tokenย you will get all content updates down to each key press.
watchModeBuffer number 150 How many milliseconds to wait on watchMode changes before applying them to Gatsby's GraphQL layer. Introduced in 7.2.0.
typePrefix string Prefix to use for the GraphQL types. This is prepended to Sanity in the type names and allows you to have multiple instances of the plugin in your Gatsby project.

Preview of unpublished content

Sometimes you might be working on some new content that is not yet published, which you want to make sure looks alright within your Gatsby site. By setting the overlayDrafts setting to true, the draft versions will as the option says "overlay" the regular document. In terms of Gatsby nodes, it will replace the published document with the draft.

Keep in mind that drafts do not have to conform to any validation rules, so your frontend will usually want to double-check all nested properties before attempting to use them.

GraphQL API

By deploying a GraphQL API for your dataset, we are able to introspect and figure out which schema types and fields are available and make informed choices based on this information.

Previous versions did not require this, but often lead to very confusing and unpredictable behavior, which is why we have now made it a requirement.

Using images

Image fields will have the image URL available under the field.asset.url key, but you can also use gatsby-plugin-image for a smooth experience. It's a React component that enables responsive images and advanced image loading techniques. It works great with this source plugin, without requiring any additional build steps.

import React from 'react'
import {GatsbyImage} from 'gatsby-plugin-image'

const sanityConfig = {projectId: 'abc123', dataset: 'blog'}

const Person = ({data}) => {
  return (
    <article>
      <h2>{data.sanityPerson.name}</h2>
      <GatsbyImage image={data.sanityPerson.profileImage.asset.gatsbyImageData} />
    </article>
  )
}

export default Person

export const query = graphql`
  query PersonQuery {
    sanityPerson {
      name
      profileImage {
        asset {
          gatsbyImageData(fit: FILLMAX, placeholder: BLURRED)
        }
      }
    }
  }
`

Note: we currently don't support the format option of gatsbyImageData. Our image CDN automatically serves the best format for the user depending on their device, so you don't need to define formats manually.

Using Gatsby's Image CDN (beta)

This plugin supports Gatsby's new Image CDN feature. To use it, follow the instructions in the section above, but substitute the gatsbyImageData field for gatsbyImage.

Using images outside of GraphQL

If you are using the raw fields, or simply have an image asset ID you would like to use gatsby-plugin-image for, you can import and call the utility function getGatsbyImageData

import {GatsbyImage} from 'gatsby-plugin-image'
import {getGatsbyImageData} from 'gatsby-source-sanity'

const sanityConfig = {projectId: 'abc123', dataset: 'blog'}
const imageAssetId = 'image-488e172a7283400a57e57ffa5762ac3bd837b2ee-4240x2832-jpg'

const imageData = getGatsbyImageData(imageAssetId, {maxWidth: 1024}, sanityConfig)

<GatsbyImage image={imageData} />

Generating pages

Sanity does not have any concept of a "page", since it's built to be totally agnostic to how you want to present your content and in which medium, but since you're using Gatsby, you'll probably want some pages!

As with any Gatsby site, you'll want to create a gatsby-node.js in the root of your Gatsby site repository (if it doesn't already exist), and declare a createPages function. Within it, you'll use GraphQL to query for the data you need to build the pages.

For instance, if you have a project document type in Sanity that you want to generate pages for, you could do something along the lines of this:

exports.createPages = async ({graphql, actions}) => {
  const {createPage} = actions

  const result = await graphql(`
    {
      allSanityProject(filter: {slug: {current: {ne: null}}}) {
        edges {
          node {
            title
            description
            tags
            launchDate(format: "DD.MM.YYYY")
            slug {
              current
            }
            image {
              asset {
                url
              }
            }
          }
        }
      }
    }
  `)

  if (result.errors) {
    throw result.errors
  }

  const projects = result.data.allSanityProject.edges || []
  projects.forEach((edge, index) => {
    const path = `/project/${edge.node.slug.current}`

    createPage({
      path,
      component: require.resolve('./src/templates/project.js'),
      context: {slug: edge.node.slug.current},
    })
  })
}

The above query will fetch all projects that have a slug.current field set, and generate pages for them, available as /project/<project-slug>. It will use the template defined in src/templates/project.js as the basis for these pages.

Checkout Creating Pages from Data Programmatically to learn more.

Remember to use the GraphiQL interface to help write the queries you need - it's usually running at http://localhost:8000/___graphql while running gatsby develop.

"Raw" fields

Arrays and object types at the root of documents will get an additional "raw JSON" representation in a field called _raw<FieldName>. For instance, a field named body will be mapped to _rawBody. It's important to note that this is only done for top-level nodes (documents).

Quite often, you'll want to replace reference fields (eg _ref: '<documentId>'), with the actual document that is referenced. This is done automatically for regular fields, but within raw fields, you have to explicitly enable this behavior, by using the field-level resolveReferences argument:

{
  allSanityProject {
    edges {
      node {
        _rawTasks(resolveReferences: {maxDepth: 5})
      }
    }
  }
}

Portable Text / Block Content

Rich text in Sanity is usually represented as Portable Text (previously known as "Block Content").

These data structures can be deep and a chore to query (specifying all the possible fields). As noted above, there is a "raw" alternative available for these fields which is usually what you'll want to use.

You can install @portabletext/react from npm and use it in your Gatsby project to serialize Portable Text. It lets you use your own React components to override defaults and render custom content types. Learn more about Portable Text in our documentation.

Using multiple datasets

If you want to use more than one dataset in your site, you can do so by adding multiple instances of the plugin to your gatsby-config.js file. To avoid conflicting type names you can use the typeName option to set a custom prefix for the GraphQL types. These can be datasets from different projects, or different datasets within the same project.

// In your gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: 'gatsby-source-sanity',
      options: {
        projectId: 'abc123',
        dataset: 'production',
      },
    },
    {
      resolve: 'gatsby-source-sanity',
      options: {
        projectId: 'abc123',
        dataset: 'staging',
        typePrefix: 'Staging',
      },
    },
  ],
}

In this case, the type names for the first instance will be Sanity<typeName>, while the second will be StagingSanity<typeName>.

Real-time content preview with watch mode

While developing, it can often be beneficial to get updates without having to manually restart the build process. By setting watchMode to true, this plugin will set up a listener which watches for changes. When it detects a change, the document in question is updated in real-time and will be reflected immediately.

If you add a token with read rights and set overlayDrafts to true, each small change to the draft will immediately be applied. Keep in mind that this is mainly intended for development, see next section for how to enable previews for your entire team.

Updating content for editors with preview servers

You can use Gatsby preview servers (often through Gatsby Cloud) to update your content on a live URL your team can use.

In order to have previews working, you'll need to activate overlayDrafts in the plugin's configuration inside preview environments. To do so, we recommend following a pattern similar to this:

// In gatsby-config.js

const isProd = process.env.NODE_ENV === "production"
const previewEnabled = (process.env.GATSBY_IS_PREVIEW || "false").toLowerCase() === "true"

module.exports = {
  // ...
  plugins: [
    resolve: "gatsby-source-sanity",
    options: {
      // ...
      watchMode: !isProd, // watchMode only in dev mode
      overlayDrafts: !isProd || previewEnabled, // drafts in dev & Gatsby Cloud Preview
    },
  ]
}

Then, you'll need to set-up a Sanity webhook pointing to your Gatsby preview URL. Create your webhook from this template, making sure you update the URL.

If using Gatsby Cloud, this should be auto-configured during your initial set-up.

โš ๏ธ Warning: if you have Gatsby Cloud previews v1 enabled on your site, you'll need to reach out to their support for enabling an upgrade. The method described here only works with the newer "Incremental CMS Preview", webhook-based system.


You can also follow the manual steps below:

  1. Get the webhook endpoint needed for triggering Gatsby Cloud previews in their dashboard.

  2. Go to sanity.io/manage and navigate to your project

  3. Under the "API" tab, scroll to Webhooks or "GROQ-powered webhooks"

  4. Add a new webhook and name it as you see fit

  5. Choose the appropriate dataset and add the Gatsby Cloud webhook endpoint to the URL field

  6. Keep the HTTP method set to POST, skip "HTTP Headers"

  7. Set the hook to trigger on Create, Update and Delete

  8. Skip the filter field

  9. Specify the following projection:

    select(delta::operation() == "delete" => {
      "operation": delta::operation(),
      "documentId": coalesce(before()._id, after()._id),
      "projectId": sanity::projectId(),
      "dataset": sanity::dataset(),
    }, {})
  10. Set the API version to v2021-03-25

  11. And set it to fire on drafts

  12. Save the webhook

Using .env variables

If you don't want to attach your Sanity project's ID to the repo, you can easily store it in .env files by doing the following:

// In your .env file
SANITY_PROJECT_ID = abc123
SANITY_DATASET = production
SANITY_TOKEN = my_super_secret_token

// In your gatsby-config.js file
require('dotenv').config({
  path: `.env.${process.env.NODE_ENV}`,
})

module.exports = {
  // ...
  plugins: [
    {
      resolve: 'gatsby-source-sanity',
      options: {
        projectId: process.env.SANITY_PROJECT_ID,
        dataset: process.env.SANITY_DATASET,
        token: process.env.SANITY_TOKEN,
        // ...
      },
    },
  ],
  // ...
}

This example is based off Gatsby Docs' implementation.

How this source plugin works

When starting Gatsby in development or building a website, the source plugin will first fetch the GraphQL Schema Definitions from a Sanity deployed GraphQL API. The source plugin uses this to tell Gatsby which fields should be available to prevent it from breaking if the content for certain fields happens to disappear. Then it will hit the projectโ€™s export endpoint, which streams all the accessible documents to Gatsbyโ€™s in-memory datastore.

In other words, the whole site is built with two requests. Running the development server, will also set up a listener that pushes whatever changes come from Sanity to Gatsby in real-time, without doing additional API queries. If you give the source plugin a token with permission to read drafts, youโ€™ll see the changes instantly.

Credits

Huge thanks to Henrique Doro for doing the initial implementation of this plugin, and for donating it to the Sanity team. Mad props!

Big thanks to the good people backing Gatsby for bringing such a joy to our developer days!

Develop

Release new version

Run "CI & Release" workflow. Make sure to select the main branch and check "Release new version".

Semantic release will only release on configured branches, so it is safe to run release on any branch.

More Repositories

1

sanity

Sanity Studio โ€“ Rapidly configure content workspaces powered by structured content
TypeScript
4,364
star
2

litter

Litter is a pretty printer library for Go data structures to aid in debugging and testing.
Go
1,437
star
3

next-sanity

Sanity.io toolkit for Next.js
TypeScript
667
star
4

nextjs-blog-cms-sanity-v3

A Next.js Blog with a Native Authoring Experience
TypeScript
392
star
5

GROQ

Specification for GROQ - The Query Language for JSON
JavaScript
380
star
6

hydrogen-sanity-demo

A starter for Hydrogen + Sanity projects
TypeScript
334
star
7

example-company-website-gatsby-sanity-combo

This is an example company website using Gatsby and Sanity in combination.
JavaScript
270
star
8

groq-js

JavaScript implementation of GROQ, the query language for JSON
TypeScript
250
star
9

mendoza

Differ for structured documents (JSON)
Go
234
star
10

template-nextjs-personal-website

A Next.js Personal Website with a Native Authoring Experience
TypeScript
233
star
11

example-frontend-next-js

An example of a Sanity powered frontend using Next.js
JavaScript
212
star
12

groq-cli

Run GROQ in your command line
JavaScript
198
star
13

block-content-to-react

Deprecated in favor of @portabletext/react
JavaScript
162
star
14

sanity-recipes

A collection of recipies / snippets / frequently asked questions about Sanity.io
JavaScript
159
star
15

sanity-plugin-media

Asset management plugin for Sanity
TypeScript
153
star
16

sanity-shopify-studio

An example Sanity Studio configured for headless Shopify projects.
TypeScript
144
star
17

sanity-template-nextjs-landing-pages

A Sanity powered landing page builder in Next.js for https://sanity.io/create
JavaScript
142
star
18

sanity-template-nextjs-clean

A clean Next.js template with a native authoring experience
TypeScript
141
star
19

squizzy

Quizzes with Squizzy the Squid!
JavaScript
139
star
20

tutorial-sanity-blog-react-next

Front-end code for the Sanity, React, Next.js tutorial.
TypeScript
136
star
21

document-internationalization

Create unique translations of a document based on its language, joined by a shared reference document
TypeScript
130
star
22

ui

UI building blocks for Sanity.
TypeScript
130
star
23

sanity-template-nextjs-app-router-personal-website

A Next.js Personal Website with a Native Authoring Experience. Uses app router.
112
star
24

preview-kit

General purpose live previews, like next-sanity
TypeScript
109
star
25

sanity-template-astro-clean

Clean starter template with Astro
Astro
105
star
26

sanity-template-kitchen-sink

A collection of demo examples
JavaScript
103
star
27

example-ecommerce-snipcart-vue

The Transglobal Candy Store: Sample front-end for the Sanity.io e-commerce schema with vue.js, nuxt.js, and snipcart
Vue
100
star
28

sanity-template-gatsby-blog

A Sanity powered Gatsby blog for https://www.sanity.io/create
JavaScript
99
star
29

sanity-template-nextjs-blog-comments

JavaScript
83
star
30

sanity-template-nextjs-ecommerce

CSS
76
star
31

orderable-document-list

Drag-and-drop Document Ordering without leaving the Editing surface
TypeScript
75
star
32

plugin-kit

Enhanced Sanity.io plugin development experience.
TypeScript
74
star
33

client

JavaScript client for retrieving, creating and patching data from Sanity.io
TypeScript
73
star
34

community-studio

Sanity Community Management Studio
TypeScript
73
star
35

example-frontend-vue-js

An example of a Sanity powered frontend using Vue.js
Vue
72
star
36

content-source-maps

Specification for the Content Source Maps standard. Used to power Visual Editing experiences.
72
star
37

sanity-template-gatsby-portfolio

A Gatsby portfolio site powered by Sanity for https://www.sanity.io/create
JavaScript
70
star
38

sanity-astro

TypeScript
65
star
39

sanity-algolia

Utilities for indexing Sanity documents in Algolia
TypeScript
61
star
40

github-action-sanity

Dockerfile
55
star
41

demo-course-platform

An example Studio and Front End demonstrating different strategies for localization with Sanity.io
TypeScript
54
star
42

sanity-plugin-mux-input

An input component that integrates Sanity Studio with MUX.com video encoding/hosting service.
TypeScript
51
star
43

sanity-plugin-graph-view

A tool for Sanity Studio to graph your content and see changes in real-time.
TypeScript
49
star
44

sanity-template-sveltekit-clean

Clean starter template with SvelteKit
Svelte
48
star
45

sanity-plugin-markdown

Markdown support in the Sanity Studio
TypeScript
48
star
46

next-recipe-app

CSS
48
star
47

sanity-template-nuxt-clean

Clean starter template with Nuxt
Vue
48
star
48

sanity-plugin-iframe-pane

Display any URL in a View Pane, along with helpful buttons to copy the URL, display a mobile size, reload the iframe or open in a new tab
TypeScript
47
star
49

hydrogen-sanity

A Sanity toolkit for Hydrogen
TypeScript
47
star
50

sanity-template-nuxt-events

A Sanity powered Conference site in Vue / Nuxt for https://www.sanity.io/create
Vue
46
star
51

netlify-form-sanity

How to use Netlify Forms and Functions to submit data to Sanity.io
HTML
46
star
52

startup-starter-kit

The Structured Content Startup Starter Kit
JavaScript
45
star
53

demo-custom-workflow

A demonstration of a custom content publishing workflow using Sanity.
HTML
44
star
54

sanity-template-sapper-blog

JavaScript
44
star
55

react-rx

React + RxJS = <3
TypeScript
43
star
56

image-url

Tools to generate image urls from Sanity content
TypeScript
43
star
57

sanity-plugin-internationalized-array

A plugin to register array fields with a custom input component to store field values in multiple languages, queryable by using the language ID as an array `_key`.
TypeScript
43
star
58

hierarchical-document-list

Plugin for editing hierarchical references in the Sanity studio.
TypeScript
41
star
59

demo-marketing-site-nextjs

TypeScript
40
star
60

gatsby-portfolio-preview-poc

Gatsby Portfolio Preview POC
JavaScript
40
star
61

groq-store

In-memory GROQ store. Streams all available documents from Sanity into an in-memory database for local querying.
TypeScript
40
star
62

sanity-studio-secrets

Hooks and chrome for handling secrets in plugins
TypeScript
39
star
63

sanity-template-nextjs-event-starter

Fully customizable starter kit for your virtual event.
TypeScript
39
star
64

vscode-sanity

Visual Studio Code extension for developing applications powered by Sanity.io
TypeScript
38
star
65

sanity-plugin-seo-pane

Run Yoast's SEO review tools using Sanity data, inside a List View Pane.
TypeScript
38
star
66

example-app-react-native

Sanity + React Native app example
JavaScript
38
star
67

themer

Experimental, creates Studio v3 themes
TypeScript
37
star
68

table

Table schema type and input component for Sanity Studio
TypeScript
37
star
69

sanity-template-eleventy-blog

Minimal blog with Eleventy and Sanity
JavaScript
37
star
70

swift-sanity

Swift
36
star
71

demo-ecommerce

TypeScript
36
star
72

sanity-template-vercel-visual-editing

TypeScript
36
star
73

webhook-toolkit

Toolkit for dealing with GROQ-powered webhooks delivered by Sanity.io
TypeScript
35
star
74

mendoza-js

Mendoza decoder in TypeScript
TypeScript
35
star
75

sanity-plugin-dashboard-widget-vercel

TypeScript
33
star
76

sanity-template-svelte-kit

A minimal, fully customizable SvelteKit front-end powered by Sanity.io data.
JavaScript
32
star
77

block-content-to-markdown

Transform Sanity block content to Markdown
JavaScript
31
star
78

visual-editing

TypeScript
31
star
79

cross-dataset-duplicator

Empower content editors to migrate Documents and Assets between Sanity Projects and Datasets from inside Sanity Studio.
TypeScript
31
star
80

sanity-plugin-dashboard-widget-netlify

Sanity Studio Dashboard Widget for triggering Netlify builds
TypeScript
29
star
81

sanity-php

PHP library for retrieving, creating and patching data from Sanity.io
PHP
28
star
82

sanity-plugin-scheduled-publishing

Schedule documents for future publishing
TypeScript
28
star
83

sanity-template-remix-clean

Clean starter template with Remix
TypeScript
28
star
84

get-it

Composable HTTP request library for node and browsers
TypeScript
26
star
85

contentful-to-sanity

Migrate from Contentful to Sanity
TypeScript
26
star
86

sanity-template-gridsome-blog

A Sanity powered Gridsome blog for sanity.io/create
JavaScript
25
star
87

asset-utils

Reusable utility functions for dealing with image and file assets in Sanity
TypeScript
24
star
88

pkg-utils

Simple utilities for modern npm packages.
TypeScript
24
star
89

sanity-plugin-hotspot-array

A configurable Custom Input for Arrays that will add and update items by clicking on an Image
TypeScript
23
star
90

dashboard

Tool for rendering dashboard widgets
TypeScript
23
star
91

jsonwebtoken-esm

jsonwebtoken wrapper that provides esm support
JavaScript
22
star
92

create-react-app-blog

JavaScript
22
star
93

demo-media-site-nextjs

A demo template for a content-driven site with longform content and newsletter capability
TypeScript
21
star
94

sanity-mux-player

Play videos in the frontend uploaded with the MUX Sanity plugin
JavaScript
21
star
95

sanity-plugin-shopify-assets

TypeScript
21
star
96

code-input

Code input and schema for Sanity Studio
TypeScript
21
star
97

sanity-nextjs-vercel-example

A bare bones example of a Vercel-deployable project with a Next.js frontend and a Sanity Studio on /studio
JavaScript
21
star
98

locales

A repository of user-contributed locale/language packs for Sanity Studio
TypeScript
21
star
99

block-content-to-html

Deprecated in favor of @portabletext/to-html
JavaScript
21
star
100

sanity-plugin-cloudinary

Official plugin for integrating Sanity Studio with Cloudinary
TypeScript
20
star