Use Sanity with Visual Editor
Visual Editor has first-class support for two-way syncing content between Sanity and Visual Editor.
# Configure Sanity as a content source
Visual Editor has a tight integration to support Sanity as a content source. This guide covers what you need to know about configuring Visual Editor to provide a two-way data sync between your Sanity project(s).
Here is an example configuration that uses Next.js as the site framework and uses a page
content type to represent pages:
// stackbit.config.ts
import { defineStackbitConfig } from "@stackbit/types";
import { SanityContentSource } from "@stackbit/cms-sanity";
export default defineStackbitConfig({
stackbitVersion: "~0.6.0",
ssgName: "nextjs",
nodeVersion: "16",
contentSources: [
new SanityContentSource({
rootPath: __dirname,
studioPath: path.join(__dirname, "studio"),
studioUrl: "https://project.sanity.studio",
projectId: process.env.SANITY_PROJECT_ID!,
token: process.env.SANITY_ACCESS_TOKEN!,
dataset: process.env.SANITY_DATASET || "production"
})
],
mapModels: ({ models }) => {
return models.map(model => {
if (model.name === "page") {
return { ...model, type: "page", urlPath: "/{slug}" };
}
return model;
});
}
});
Notice the following:
SanityContentSource
is being loaded from the@stackbit/cms-sanity
which must be installed first. This package is not needed in your production site.- Sanity is being configured using local environment variables. Visual Editor automatically loads a
.env
in the root of your project. - There is a content type with an ID of
page
that is being used to store page data in Sanity. That content type has a field with nameslug
that determines the URL path at which the page is made available.
Note
If you are using a visual editor with two Sanity content sources, project ID (srcProjectId
) in the saved preset will be prefixed with the Sanity dataset title (example: "srcProjectId": "o0o3tm7x:production"
). That means if you have a preset without a prefixed dataset title, it won’t be shown in the visual editor.
# Prerequisites
To be able to work with Sanity, you must first have the following:
A Sanity project with content in a dataset.
The proper API keys and related environment variables that can access your content. (See options below.)
Installed
@stackbit/cms-sanity
package as a development dependency. (We also recommend@stackbit/types
to help with configuration.)npm install -D @stackbit/types @stackbit/cms-sanity
# Usage
import { SanityContentSource } from "@stackbit/cms-sanity";
new SanityContentSource({
rootPath: "...",
studioPath: "...",
studioUrl: "...",
projectId: "...",
token: "...",
dataset: "...",
studioInstallCommand: "..."
});
# Options
The following are all required options unless otherwise noted:
dataset
: name of the dataset to be used when editing the content. This is often set asproduction
.projectId
: unique ID value assigned to your Sanity project.rootPath
: absolute path to the front-end project. This is note the path to the studio, which is covered bystudioPath
.studioPath
: (optional) absolute path to the studio project, which is often contained within therootPath
project directory. The default path is:${rootPath}/studio
.studioInstallCommand
: (optional) custom command to run when installing Sanity studio for your visual editor with the cloud setup. This can be ignored if using the typical studio installation pattern. To skip install the installation process entirely, set to an unobtrusive command such asecho 'skipping install'
.studioUrl
: (optional) the URL to the deployed Sanity Studio instance. The visual editor will use this link in the toolbar that appears when you highlight an object. If not set, the link to Sanity in the toolbar will be disabled.token
: API access token.
# Store sensitive values
Sensitive values can be stored in a .env
file, which will then be available when Visual Editor configuration file is loaded.
# .env
SANITY_PROJECT_ID="..."
SANITY_ACCESS_TOKEN="..."
SANITY_DATASET="..."
# Model type inference
The Sanity CSI module makes the following inferences:
- Object models in Sanity are automatically inferred as Visual Editor
object
models. - Document models are inferred as Visual Editor
data
models.
Therefore, page
models must be defined using the modelExtensions
property.
# Custom Studio installation
If you need to run a custom command when installing Sanity Studio in the cloud, use the studioInstallCommand
option.
new SanityContentSource({
studioInstallCommand: "..."
// ...
});
# Skip Studio installation
To skip the Sanity Studio installation process entirely, specify an arbitrary and unobtrusive command. For example, to simply print "skipping install" to the console, do this:
new SanityContentSource({
studioInstallCommand: `echo 'skipping install'`
// ...
});
# Provision Sanity
Note
This is only relevant when creating a Visual Editor project from a template.
You don't need Sanity provisioning if you have already set up a Sanity project for your project, or if you plan to manually create and configure a project.
Visual Editor will handle provisioning a new Sanity project, along with the initial payload of models and content when creating a new project from a template.
# Export content from Sanity
In most cases, projects that can be provisioned with Sanity as a content source have a Sanity project as the source of truth for duplicated projects.
The first step in preparing your project to be duplicated is to export the content schema and the initial site contents from your Sanity project.
Be sure to configure the export to include a compressed file of all appropriate schemas, documents, and assets. Commit the exported data file to your project. See here for an example.
Tip
Here is an export script we often use in Sanity projects. It generates a export.tar.gz
file, like the one found in our Sanity starter.
# Import configuration
Once you've exported the content (and committed the data file), all that is left to do is add configuration for importing the content during the provisioning process.
The following properties should be added to an import
property in your Visual Editor configuration file. All properties are required and are strings, unless otherwise noted.
contentFile
: path relative to the root of the project, pointing to the file that contains the exported data. This should be compressed (typically something likeexport.tar.gz
)datasetEnvVar
: a string representing the name of the environment variable that specifies the dataset to which the imported content should be added. This is not the name of the dataset, but the name of the environment variable.deployGraphql
: (boolean) set totrue
to ensure that Visual Editor deploys Sanity GraphQL API when creating the site.deployStudio
: (boolean) set totrue
to ensure that Visual Editor deploys Sanity Studio when creating the site.projectIdEnvVar
: a string representing the name of the environment variable that contains the Sanity project ID. This is not the project ID itself, but the name of the environment variable.sanityStudioPath
: path to the studio directory, relative to the root of the project.tokenEnvVar
: a string representing the name of the environment variable that contains the Sanity API access token. This is not the token itself, but the name of the environment variable.type
: set tosanity
.
// stackbit.config.js
export default {
contentSources: [
new SanityContentSource({
rootPath: __dirname,
studioPath: path.join(__dirname, "studio"),
studioUrl: "",
projectId: process.env.SANITY_PROJECT_ID,
token: process.env.SANITY_ACCESS_TOKEN,
dataset: process.env.SANITY_DATASET || "production"
})
],
mapModels: ({ models }) => {
// page definitions and model decorations ...
},
import: {
contentFile: "sanity-export/export.tar.gz",
datasetEnvVar: "SANITY_DATASET",
deployGraphql: false,
deployStudio: true,
projectIdEnvVar: "SANITY_PROJECT_ID",
sanityStudioPath: "studio",
tokenEnvVar: "SANITY_ACCESS_TOKEN",
type: "sanity"
}
// other properties ...
};
Did you find this doc useful?
Your feedback helps us improve our docs.