Visual Editing

The Presentation tool

The Presentation tool enables Visual Editing for interactive live previews. This is how you set it up within your studio.

The Presentation Tool enables Visual Editing by integrating a live preview of your web application within Sanity Studio.

It provides:

  • Live preview: See draft content updates in real-time within the Studio
  • Click-to-edit: Interactive overlays that help content creators find and edit the right fields
  • Page building: Advanced capabilities for adding, moving, and removing content sections
  • Preview sharing: A way for content creators to share a preview with others
  • Locations: Add shortcuts to open preview where a document is used from the Structure tool

For Studio-user friendly documentation, go to the user guide of the Presentation tool.

a screenshot of a personal website with the title project alpha
The Presentation tool is the primary way content editors experience Visual Editing

Prerequisites

To use the Presentation tool, your studio must be updated to v3.40.0 or preferably latest.

npm install sanity@latest

Protip

Configuration steps

Similarly to the other tools and plugins, you add the Presentation tool to your main studio configuration file. The example below shows a typical setup for a Next.js project where specific endpoints are supplied to let Sanity Studio put the front end into preview mode.

Basic configuration

  • Import presentationTool from sanity/presentation
  • Add it to the plugins array
  • Add your frontend-specific details, such as the initial URL and endpoints for enabling or disabling preview mode
// sanity.config.ts
// ...all other imports
import { presentationTool } from 'sanity/presentation'

export default defineConfig({
  // ... all other config settings
  plugins: [
    // ...all other plugins
    presentationTool({
      previewUrl: {
        initial: 'https://my-cool-site.com',
        previewMode: {
          enable: '/api/draft-mode/enable',
          disable: '/api/draft-mode/disable',
        },
      },
      allowOrigins: ['http://localhost:*'],
    }),
  ],
})

Protip

Map content to front-end routes

To map Sanity documents to their corresponding front-end routes, create a resolve.locations configuration. This object tells the Presentation Tool how each document type corresponds to a route in the front end.

The locations resolver lets the studio know where content appears in front end
The locations resolver lets the studio know where content appears in front end

Protip

Add route definitions for your document types

In the example below, we map documents of type product to /products/${slug} and add them to the top-level index. You will need to substitute your own types and routes as appropriate.

// ./lib/presentation/resolve.ts
import {defineDocuments, defineLocations} from 'sanity/presentation'

// Configures the "Used on x pages" banner
export const locations = {
  // Map document types to frontend routes
  product: defineLocations({
    select: {title: 'title', slug: 'slug.current'},
    resolve: (doc) => ({
      locations: [
        {title: doc.title, href: `/products/${doc.slug}`},
        {title: 'Products Index', href: `/products`},
      ],
    }),
  }),
  // ...
})

// Configures documents presentation tool should open by default when navigating to an URL
export const mainDocuments = defineDocuments([
  {
    route: '/products/:slug',
    filter: `_type == "product" && slug.current == $slug`,
  },
  // ...
])

Import the resolver function into sanity.config.ts and pass it to the presentationTool config

import {defineConfig} from 'sanity'
import {presentationTool} from 'sanity/presentation'
import {locations, mainDocuments} from './lib/presentation/resolve'

export default defineConfig({
  // ...
  plugins: [
    presentationTool({
      resolve: {locations, mainDocuments},
      previewUrl: {
        initial: 'https://my-cool-site.com',
        previewMode: {
          enable: '/api/draft-mode/enable',
          disable: '/api/draft-mode/disable',
        },
      },
      allowOrigins: ['http://localhost:*'],
    }),
  ],
})

Multi-origin configuration

Sometimes you need multiple allowed origins, like in scenarios where a single studio handles the content many sites or properties. allowOrigins accepts an array of origins that Presentation will recognize.

You can also provide an async function to configure it dynamically.

Configuration reference

The Presentation tool takes the following configuration attributes:

  • RequiredpreviewUrlstring | PreviewUrlOption

    Accepts an object with keys for setting the initial URL of your front end, as well as defining endpoints for enabling or disabling preview mode in your front end. Also accepts a plain string in the shape of a URL for projects that don't need the detailed setup.

  • iconReact component

    Sets an icon to represent the Presentation tool in the Studio's navigation bar. To use Sanity icons, install the @sanity/icons package.

  • namestring

    Sets a name for the Presentation tool. It's not visually represented in the Studio UI, but it’s included in the Studio's URL for the Presentation tool.

    This is useful if you want to implement multiple instances of Presentation, for example, for different channels, domains, or preview environments.

    Default value: presentation

  • titlestring

    Sets the title that is displayed in the Studio's navigation bar. Keep it short and descriptive to help editorial users understand what they can do with the tool.

    Default value: Presentation

  • resolve{ mainDocuments?: DocumentResolver[]; locations?: DocumentLocationResolvers | DocumentLocationResolver }

    Return the document-to-URL mapping to add affordances to quickly open documents in the Presentation tool. Go to the Presentation Resolver API documentation to learn more.

  • allowOriginsstring[] | (context) => Promise<string[]>

    A list of URLPattern strings that defines what URL origins can be opened in the preview iframe. The URL origin returned in previewUrl.initial is always allowed. Other URLs that may be manually entered in the URL bar, defined in resolve.locations and such will have to be in the allow list or Presentation Tool will refuse to connect. URL origins you specify will be able to send postMessage events to your Sanity Studio and can run live preview queries, don't add an URL origin you don't trust.

Was this page helpful?