Visual Editing

Visual Editing with Next.js Pages Router

Get started with Sanity Visual Editing in a new or existing Next.js application using the Pages Router.

Following this guide will enable you to:

  • Render overlays in your application, allowing content editors to jump directly from Sanity content to its source in Sanity Studio.
  • Edit your content and see changes reflected in an embedded preview of your application in Sanity’s Presentation Tool.
  • Provide instant updates and seamless switching between draft and published content.

Gotcha

Prerequisites

Next.js application setup

The following steps should be performed in your Next.js application.

Install dependencies

Install the dependencies that will provide your application with data fetching and Visual Editing capabilities.

Add environment variables

Create a .env file in your application’s root directory to provide Sanity-specific configuration.

You can use Manage to find your project ID and dataset, and to create a token with Viewer permissions which will be used to fetch preview content.

The URL of your Sanity Studio will depend on where it is hosted or embedded.

Application setup

Configure the Sanity client

Create a Sanity client instance to handle fetching data from Content Lake.

Configuring the stega option enables automatic overlays for basic data types when preview mode is enabled. You can read more about how stega works.

Draft mode

Draft mode allows authorized content editors to view and interact with draft content. Presentation Tool and sharing communicate with your Next.js app to enable or disable draft mode.

Create an API endpoint (in src/pages/api) to enable draft mode when viewing your application in Presentation Tool.

Similarly, create an API endpoint to disable draft mode.

Create a new component with a link to the disable endpoint. We add conditional logic to only render this for content authors when viewing draft content in a non-Presentation context. The code in this example uses minimal styling, but you may wish to create a more suitable banner that fits your layout.

Enable Visual Editing

Create a Visual Editing wrapper component.

The <VisualEditing> component handles rendering overlays, enabling click to edit, and refreshing pages in your application when content changes. Render it alongside the <DisableDraftMode> component you created above.

Embedded studios

We provide a basic refresh mechanism that will reload the page when changes are made in Presentation Tool. You can optionally use loaders to provide seamless updates.

<VisualEditing /> props

The <VisualEditing /> component accepts the following optional props introduced in @sanity/visual-editing 5.5.0.

keepStegaOnCopy (boolean, optional)

Default: false. By default, <VisualEditing /> intercepts copy events and automatically strips stega encoding from both text/plain and text/html clipboard payloads. This ensures that users copying text from the preview page do not get invisible stega characters in their clipboard. Pass keepStegaOnCopy to opt out of this behavior and preserve stega encoding in clipboard output.

onSuspiciousStega (callback, optional)

An opt-in callback that reports stega encoding found in unsafe DOM placements. When provided, <VisualEditing /> audits the DOM for stega in locations where it should not appear, including:

  • Element attributes such as class, id, href, src, style, data-*, and others
  • Inside <head>: title, meta[content], and JSON-LD script blocks
  • Text content inside <script> or <style> elements
  • Textarea form values
  • The page URL

Each report includes the kind, element, attribute (if applicable), value, cleaned, and sanity (decoded edit information).

<VisualEditing
  onSuspiciousStega={(reports) => {
    for (const report of reports) {
      console.warn(`Stega found in ${report.kind}`, report)
    }
  }}
/>

Development use

In the root layout file, dynamically import and render the <SanityVisualEditing> wrapper component when draft mode is enabled.

Set up loaders

Create a new file to configure loaders. Call setServerClient, with the client instance which should be used to fetch data on the server.

We also create a helper function to return fetch options based on the draft mode state, and export this alongside loadQuery for convenience.

Render a page in preview mode

In getStaticProps use the loadQuery function created above. The initial data returned here is passed to useQuery in the page component.

When in Presentation Tool, useQuery will handle live updates as content is edited.

Studio setup

To set up Presentation Tool in your Sanity Studio, import the tool from sanity/presentation, add it to your plugins array, and set previewUrl to the base URL of your application.

We similarly recommend using environment variables loaded via a .env file to support development and production environments.

Optional extras

Add data attributes for overlays

useQuery also returns an encodeDataAttribute helper method for generating data-sanity attributes. These attributes give you direct control over rendering overlays in your application, and are especially useful if not using stega encoding.

Next steps

You now have a Next.js Pages Router application with click-to-edit overlays, live updates in Presentation Tool, and draft mode switching. To go deeper, learn how stega encoding works or take direct control of overlays in your application.

Was this page helpful?