I'm using Sanity.io, GatsbyJS 3.x
Watch mode works great when you update content in the CMS, except for when the content you edit is part of a referenced schema of type 'document'.
Put another way, changes made to a document referenced by another document will not re-render the page despite having watch mode on and configured properly.
For example, here is a snippet from my Page schema.
...
{
name: "content",
type: "array",
title: "Page Sections",
description: "Add, edit, and reorder sections",
of: [
{
type: 'reference',
to: [
{ type: 'nav' },
{ type: 'section' },
{ type: 'footer' }
]
}
],
},
...
The above schema references a
Each of these are type 'document'. See the example below.
export default {
type: 'document',
name: 'section',
title: 'Page Sections',
fields: [
{
name: 'meta',
title: 'Section Meta Data',
type: 'meta'
},
...
I want to reference a document, rather than an object, because I need to use the content created based on these schemas to be re-used in throughout the application.
Finally, I've configured the source plugin correctly for watch mode.
Gatsby Config is set properly
{
resolve: `gatsby-source-sanity`,
options: {
projectId: `asdfasdf`,
dataset: `template`,
watchMode: true,
overlayDrafts: true,
token: process.env.MY_SANITY_TOKEN,
},
},
In the CMS / Studio, when you edit one of the fields, you can see Gatsby re-compile in dev mode from the terminal. However, the page does not auto reload and display the changes made to the referenced document.
I've tried reloading the page with the reload button and via hard refresh, the changes do not render.
The only way to render the changes is to go back to the CMS and edit a field on the main “Page” document. Then it refreshes immediately.
Am I doing something wrong? Is this expected behavior? Is there a way to get this to work?
For those that run across this issue, I was able to answer my own question. I hope this saves you the day's it took me to find a solution.
You need to explicitly query the referenced document in order for watch mode to work properly.
The gatsby-source-sanity plugin provides convenience queries that start with _raw for array types. When you use the _raw query in your GraphQL query, it will not trigger watch mode to reload the data. You need to explicitly query the referenced document in order for watch mode to work properly. This may have to do with how the plugin sets up listeners and I don't know if this is a bug or a feature.
My Page Document has the following schema
{
name: "content",
type: "array",
title: "Page Sections",
description: "Add, edit, and reorder sections",
of: [
{
type: "reference",
to: [
{ type: "nav" },
{ type: 'section' },
],
},
],
},
The section is a reference to a section document.
{ type: 'section' }
The reason I'm not using an object is because I want the page sections to be re-usable on multiple pages.
Assuming you have watch mode enabled properly in your gatsby-config.js file, watch mode, like so...
// gatsby-config.js
{
resolve: `gatsby-source-sanity`,
options: {
projectId: `asdf123sg`,
dataset: `datasetname`,
watchMode: true,
overlayDrafts: true,
token: process.env.SANITY_TOKEN,
},
},
Then you should see the following behavior:
You'll see the following scroll in your terminal window.
success Re-building development bundle - 1.371s
success building schema - 0.420s
success createPages - 0.020s
info Total nodes: 64, SitePage nodes: 9 (use --verbose for breakdown)
success Checking for changed pages - 0.001s
success update schema - 0.081s
success onPreExtractQueries - 0.006s
success extract queries from components - 0.223s
success write out requires - 0.002s
success run page queries - 0.010s - 1/1 99.82/s
This works great if you are querying the main document or any referenced objects. However, if you are querying any references to another document then there is one gotcha you need to be aware of.
When you use the _raw query in your GraphQL query, it will not trigger watch mode to reload the data. You need to explicitly query the referenced document in order for watch mode to work properly.
export const PageQuery = graphql`
fragment PageInfo on SanityPage {
_id
_key
_updatedAt
_rawContent(resolveReferences: {maxDepth: 10})
}
`
export const PageQuery = graphql`
fragment PageInfo on SanityPage {
_id
_key
_updatedAt
_rawContent(resolveReferences: {maxDepth: 10})
content {
... on SanitySection {
id
}
}
}
`
Here is where I am explicitly querying the document that is being referenced in the 'content' array.
content {
... on SanitySection {
id
}
}
You don't actually need to use the data that results from that query, you simply need to include this in your query.
My guess is that this informs the gatsby-source-sanity plugin to set up a listener, whereas the _rawContent fragment does not.
Not sure if this is a feature, bug, or just expected behavior. At the time of writing the versions were as follows.
"gatsby": "3.5.1",
"gatsby-source-sanity": "^7.0.0",