Unlock seamless workflows and faster delivery with our latest releases- get the details
Experimental feature

Content mapping

Learn how to set up and configure content mapping to bridge the gap between Sanity Create and Sanity Studio, giving your content team the best of both worlds.

Content mapping between Sanity Create and Sanity Studio is an excellent addition to every content team's toolbox. It grants the best of both worlds:

  • A free-form creative writing space with a context-aware writing assistant for the ideation phase
  • A powerful studio for structured content operations when it's time to put that content to work

All without content teams wasting precious time and bandwidth copying and pasting their work from one place to the other.

Visit the introduction to content mapping to learn more about how content mapping works once implemented. Read on to learn how to set it up.

Enable content mapping in Sanity Studio

The process of setting up your studio differs slightly depending on your hosting arrangements, so we will briefly explain the general steps to be done in broad terms and then show how it's specifically done in each of these common scenarios:

  • Studio hosted with Sanity. Which is to say you have a studio URL that looks something like <my-cool-project>.sanity.studio
  • Studio hosted as a standalone web app anywhere else
  • Studio embedded in a Next.js app

Extracting manifest JSON files for your project

Content mapping works by creating a studio deployment with a couple of descriptive files that Sanity Create can examine to learn about your project and your content model. These files are generated automatically as part of the deployment process, but can be configured to meet your specific needs or even disabled entirely. Create expects to find these files in the /static -directory of your studio. Specifically at these locations, relative to your root studio URL:

  • /static/create-manifest.json
  • /static/<schema-hash>.create-schema.json

Note that there can be one or more files matching the pattern shown in the second bullet. The first file contains an overview of your project, including workspaces and content types, while the remaining files include detailed schema information for each content type. Sanity Create will access these files over HTTP, which means they'll need to be accessible without any sort of authentication and in the expected place.

As of version 3.62.3, Sanity Studio includes a CLI command used to generate these manifest files:

sanity manifest extract

Running this command with no options specified will result in the manifest files being generated in the dist/static-directory of your project, ready to be deployed with your next studio build.

Read on for specific implementation details.

Deploying with Sanity hosting

If you are using Sanity's hosting service, you get the most straightforward route. To set up your project to automatically generate the manifest on every deployment, follow these steps:

  • Make sure your project is updated to v3.62.3 or later of Sanity Studio. @latest is always recommended!

Protip

Studios hosted with Sanity are prime candidates for auto-updating! The main studio bundle is kept up to date automatically on each new release, while your custom code is left untouched.

  • Configure your studio host in sanity.cli.ts. This value should be only the bit that goes before the .sanity.studio part of the address. So if your studio is hosted at my-cool-project.sanity.studio, you'd add the following:
// ./sanity.cli.ts
import { defineCliConfig } from 'sanity/cli';

export default defineCliConfig({
  api: {
    // ... project details
  },
  // ... other config
studioHost: 'my-cool-project',
})

Protip

Adding the studioHost property to your CLI-config file is a meant to be a convenience, and is not a required step. If you leave it out you will be prompted during deployment to either choose an existing hostname or create a new one.

  • Deploy your studio using sanity deploy.

The Sanity CLI will automatically build your studio and manifest files and deploy them to the configured host. The manifest files will be available at:

  • <studioHost>.sanity.studio/static/create-manifest.json
  • <studioHost>.sanity.studio/static/<schema-hash>.create-schema.json

Deploying with Other Hosting Solutions

If you are not using Sanity's hosting service, you will need to:

  1. Generate the manifest files using sanity manifest extract.
  2. Serve the manifest files over HTTP GET from <custom-studio-url>/static/<manifest-file> (see filenames above).
  3. Ensure the manifest files are publicly accessible on the internet without authentication.
  4. Add the studio URL in your Sanity Manage project settings.

Deploying as an embedded studio in Next.js

For Next.js projects with embedded studios, you can generate the manifest files as part of your build process:

sanity manifest extract --path public/static && next build

By placing the manifest files in the public/static folder, Next.js will serve them over HTTP GET for Sanity Create when you deploy your application.

Troubleshooting manifest extraction

Disable manifest extract on deploy

To disable manifest extract during sanity deploy , set
SANITY_CLI_EXTRACT_MANIFEST_ENABLED=false

Show manifest errors

When the manifest extract command is run as part of the deployment process, error reporting is silenced by default.

To show errors set
SANITY_CLI_EXTRACT_MANIFEST_LOG_ERRORS=true

Common pitfalls

Manifest extraction has the same limitations as GraphQL and Sanity TypeGen; the studio config has to be parsable in a mock node browser environment. Things that reference the window in a global context are a prime example of things that go unexpectedly wrong.

Enabling or disabling "Start in Create" Functionality

As of v3.67.0 of Sanity Studio the Start in Create-banner is shown by default for all compatible document types. Depending on your setup, you might see a fully functional or a disabled button. This section will assist you in either making the most of the feature, or disabling it if you so wish.

Start in Create is disabled

If the Start in Create-button is visible but disabled, refer to the section on setting up your studio for content mapping in this article. Make sure the following conditions are met:

  • The origin of the current URL is listed under Studios in sanity.io/manage (or fallbackStudioOrigin is provided)
  • [origin]/static/create-manifest.json is available over HTTP GET

Gotcha

Sanity Create does not acknowledge initial value templates, or indeed initial values. Any document type that relies on initial values will not display the Start in Create-button.

Start in Create shows a warning in development

If your studio correctly displays a functional Start in Create-button in your production environment (i.e., your deployed studio), but not in development (i.e., while running locally on your computer) this is expected behavior. You should see a small ⓘ-icon next to the button which will provide some more info when clicked.

The ⓘ-icon next to the Start in Create-button only shows up when running on localhost
Clicking the ⓘ will open a popover revealing the state of your local setup.

For the Start in Sanity Create-button to work as expected on localhost, you need to configure beta.create.fallbackStudioOrigin. This value must exactly match the name shown for a studio deployment in the Sanity project management console, and the studio must have create-manifest.json available.

// sanity.config.ts
import { defineConfig } from 'sanity';

export default defineConfig({
  // ...rest of config
  beta: {
    create: {
      startInCreateEnabled: true,
      fallbackStudioOrigin: 'my-cool-project.sanity.studio'
    }
  }
})

Keep in mind that when the fallback origin is used, Sanity Create will use the schema types and dataset from the deployed studio, not from your local development environment.

To see data synced from Sanity Create in your local studio, ensure that the deployed fallback studio uses the same workspace and schemas as your local configuration.

I don't want the Start in Create-button

You can selectively remove the Start in Create-button for individual document types, as discussed in the upcoming section on configuring schemas for content mapping, or disable it for all content types in your workspace.

To fully remove the Start in Create-button for all new documents in the studio, set beta.create.startInCreateEnabled: false in your sanity.config.ts file.

// sanity.config.ts
import { defineConfig } from 'sanity';

export default defineConfig({
  // ...rest of config
  beta: {
    create: {
      startInCreateEnabled: false,
    }
  }
})

Configuring Schemas for Content Mapping

To tailor how Sanity Create handles your studio schema, you can use the options.sanityCreate configuration that has been added to all schema types.

This configuration allows you to:

  • Exclude specific types or fields from appearing in Sanity Create using options.sanityCreate.exclude
  • Provide additional context to the mapping agent about the intended purpose of a type or field using options.sanityCreate.purpose

Protip

Excluding fields that aren't useful to edit in Create is beneficial in more than one way! You'll deliver a cleaner and more intuitive experience to your content team, and you'll avoid problems that can occur in Create when faced with overly complex schemas.

Be particularly diligent with your exclusions for schemas that:

  • Are really big
  • Have a high number of types
  • Have big arrays of several different types

Excluding Types and Fields

To prevent a document type from being selectable in Sanity Create, set the exclude option to true:

import {defineType} from 'sanity'

export default defineType({
  name: 'policy',
  type: 'document',
  description: 'Super-sensitive stuff',
  options: {
    sanityCreate: {
      exclude: true
    },
  },
  fields: [
    // ...
  ]
});

Similarly, you can exclude specific fields within a document type by setting options.sanityCreate.exclude to true on the field level:

import {defineField, defineType} from 'sanity'

export default defineType({
  name: 'article',
  type: 'document',
  fields: [
    defineField({
    name: 'internalNotes',
    type: 'text',
options: {
sanityCreate: { exclude: true }
}
}), // ... ] });

In this example, the article type is still available in Create, but the internalNotes field will not be shown or possible to target for mapping.

Adding Context with Purpose

The options.sanityCreate.purpose option allows you to provide additional context to the mapping agent about the intended purpose or usage of a specific type or field. This can help the agent make more accurate decisions when mapping content from Sanity Create to your studio schema.

For example, if you have a tags field in your schema that’s intended specifically for SEO keywords rather than general content categorization, you can clarify this using the purpose option:

import {defineField, defineType} from 'sanity'

export default defineType({
  name: 'article',
  type: 'document',
  fields: [
    {
      name: 'tags',
      type: 'array',
      of: [{type: 'string'}],
options: {
sanityCreate: {
purpose: 'SEO keywords to improve search visibility, not general categorization tags.',
},
},
}, // ... ], })

Consider using the purpose option when added clarity would be helpful. Often, the automatic mapping will get it right, so give it a try first and add purpose details only if needed to refine the mapping.

Schema Snapshots and Syncing

Once a Sanity Create schema is linked to a Studio schema, Sanity Create will keep a snapshot of the schema manifest for future use. This means that any changes made to the schema on the Studio side will not be immediately reflected in Sanity Create.

To update the schema snapshot in Sanity Create after making changes in the Studio, editors need to:

  1. Unlink the current schema in Sanity Create
  2. Disconnect the connected studio
  3. Reconnect to the studio and relink to the updated schema

This process ensures that Sanity Create always works with the most recent version of your studio's schema, preventing any inconsistencies or mapping issues that may arise from schema changes.

Was this article helpful?