---
title: "Visual Editing · Sanity × Nuxt UI"
description: "Turn on the live preview in the Presentation tool, locally and in production."
canonical_url: "https://sanity-nuxtui.vercel.app/docs/visual-editing"
meta:
  "og:description": "Turn on the live preview in the Presentation tool, locally and in production."
  "og:image": "https://sanity-nuxtui.vercel.app/_og/d/c_Page%2Ctitle_Visual%2BEditing%2Cdescription_~VHVybiBvbiB0aGUgbGl2ZSBwcmV2aWV3IGluIHRoZSBQcmVzZW50YXRpb24gdG9vbCwgbG9jYWxseSBhbmQgaW4gcHJvZHVjdGlvbi4%2Cheadline_Docs%2CsiteName_~U2FuaXR5IMOXIE51eHQgVUk%2Cp_Ii9kb2NzL3Zpc3VhbC1lZGl0aW5nIg%2Cs_sM6piyz9ALUg3cOX.png"
  "og:image:height": "630"
  "og:image:type": image/png
  "og:image:width": "1200"
  "og:title": "Visual Editing · Sanity × Nuxt UI"
  "twitter:image": "https://sanity-nuxtui.vercel.app/_og/d/c_Page%2Ctitle_Visual%2BEditing%2Cdescription_~VHVybiBvbiB0aGUgbGl2ZSBwcmV2aWV3IGluIHRoZSBQcmVzZW50YXRpb24gdG9vbCwgbG9jYWxseSBhbmQgaW4gcHJvZHVjdGlvbi4%2Cheadline_Docs%2CsiteName_~U2FuaXR5IMOXIE51eHQgVUk%2Cp_Ii9kb2NzL3Zpc3VhbC1lZGl0aW5nIg%2Cs_sM6piyz9ALUg3cOX.png"
---

> Index of every page on this site: [llms.txt](https://sanity-nuxtui.vercel.app/llms.txt)

[Docs](https://sanity-nuxtui.vercel.app/docs)

# **Visual Editing**

Turn on the live preview in the Presentation tool, locally and in production.

The Presentation tool in the Studio shows the site with drafts, lets editors click any text to edit it, and drag blocks to reorder them. It needs a read token on the site.

## Turn it on

1. Create a token with the ****Viewer**** role:

```
pnpm --filter studio exec sanity tokens add "Preview" --role viewer
```

1. Add it to `apps/web/.env`, with the address of the Studio:

apps/web/.env

```
NUXT_SANITY_API_READ_TOKEN=sk...NUXT_SANITY_STUDIO_URL=http://localhost:3333
```

1. Restart the site and open ****Presentation**** in the Studio.

**The token stays on the server**

It is only used by the Nuxt server to read drafts. Never expose it with a NUXTPUBLIC variable.

## How drafts stay private

Visitors never see drafts. The Presentation tool opens `/preview/enable` with a one-time secret; the site checks the secret with Sanity and sets a preview cookie for that browser only. `/preview/disable` removes it. Drafts and stega markers are only used in a browser with that cookie.

## Production and caching

Cached pages cannot show drafts, so the cache has to be skipped for editors:

- ****Vercel****: one deployment does both. Pages stay cached with ISR for visitors, and `/preview/enable` also sets Vercel's `__prerender_bypass` cookie, so the editor's browser skips the cache. The bypass token is derived from the read token; see `server/preview/enable.ts` and `isrBypassToken` in `nuxt.config.ts`.
- ****Other hosts**** (Cloudflare, Node): their cache cannot be skipped for a single visitor, so caching turns off when a read token is set. Use two deployments of `apps/web`: the public site without a token, and a preview deployment with it.

## Point the Studio at the site

The Studio opens `SANITY_STUDIO_PREVIEW_URL`. `sanity dev` reads `apps/studio/.env`, and `sanity deploy` also reads `apps/studio/.env.production`, so keep `http://localhost:3000` for local work and put the deployed site in `.env.production`. The hosted Studio can still preview a local dev server: type its address in the Presentation address bar.

Add the site to the CORS origins of the project, with credentials:

```
pnpm --filter studio exec sanity cors add https://example.com --credentials
```

## Where documents appear

`apps/studio/presentation/resolve.ts` tells the Presentation tool which URLs show a document, so an editor opening a document in Presentation lands on the right page. Update it when you add a document type with its own URL.

**Safari blocks cookies in cross-site frames**

Live preview from a hosted Studio (.sanity.studio) to your site's domain works in Chrome, Edge and Firefox. Editors on Safari can use the Studio for writing and another browser for previewing, or you can host the Studio on the site's own domain.

[**Languages** How document translations, language prefixes, fallbacks and translated interface text work.](https://sanity-nuxtui.vercel.app/docs/languages) [**Search** The search palette, its GROQ query and what it needs from the hosting.](https://sanity-nuxtui.vercel.app/docs/search)

```json
{"@context":"https://schema.org","@graph":[{"@id":"https://sanity-nuxtui.vercel.app/#website","@type":"WebSite","name":"Sanity × Nuxt UI","url":"https://sanity-nuxtui.vercel.app/","publisher":{"@id":"https://sanity-nuxtui.vercel.app/#identity"}},{"@id":"https://sanity-nuxtui.vercel.app/docs/visual-editing#webpage","@type":"WebPage","dateModified":"2026-10-16T02:29:18Z","description":"Turn on the live preview in the Presentation tool, locally and in production.","name":"Visual Editing","url":"https://sanity-nuxtui.vercel.app/docs/visual-editing","isPartOf":{"@id":"https://sanity-nuxtui.vercel.app/#website"},"potentialAction":[{"@type":"ReadAction","target":["https://sanity-nuxtui.vercel.app/docs/visual-editing"]}]},{"@id":"https://sanity-nuxtui.vercel.app/#identity","@type":"Organization","name":"Sanity × Nuxt UI","url":"https://sanity-nuxtui.vercel.app"},{"@id":"https://sanity-nuxtui.vercel.app/docs/visual-editing#article","@type":"Article","dateModified":"2026-10-16T02:29:18Z","description":"Turn on the live preview in the Presentation tool, locally and in production.","headline":"Visual Editing","inLanguage":"en","thumbnailUrl":"https://sanity-nuxtui.vercel.app/_og/d/c_Page%2Ctitle_Visual%2BEditing%2Cdescription_~VHVybiBvbiB0aGUgbGl2ZSBwcmV2aWV3IGluIHRoZSBQcmVzZW50YXRpb24gdG9vbCwgbG9jYWxseSBhbmQgaW4gcHJvZHVjdGlvbi4%2Cheadline_Docs%2CsiteName_~U2FuaXR5IMOXIE51eHQgVUk%2Cp_Ii9kb2NzL3Zpc3VhbC1lZGl0aW5nIg%2Cs_sM6piyz9ALUg3cOX.png","author":{"@id":"https://sanity-nuxtui.vercel.app/#identity"},"image":{"@id":"https://sanity-nuxtui.vercel.app/#/schema/image/1"},"isPartOf":{"@id":"https://sanity-nuxtui.vercel.app/docs/visual-editing#webpage"},"mainEntityOfPage":{"@id":"https://sanity-nuxtui.vercel.app/docs/visual-editing#webpage"},"publisher":{"@id":"https://sanity-nuxtui.vercel.app/#identity"}},{"@id":"https://sanity-nuxtui.vercel.app/#/schema/image/1","@type":"ImageObject","contentUrl":"https://sanity-nuxtui.vercel.app/_og/d/c_Page%2Ctitle_Visual%2BEditing%2Cdescription_~VHVybiBvbiB0aGUgbGl2ZSBwcmV2aWV3IGluIHRoZSBQcmVzZW50YXRpb24gdG9vbCwgbG9jYWxseSBhbmQgaW4gcHJvZHVjdGlvbi4%2Cheadline_Docs%2CsiteName_~U2FuaXR5IMOXIE51eHQgVUk%2Cp_Ii9kb2NzL3Zpc3VhbC1lZGl0aW5nIg%2Cs_sM6piyz9ALUg3cOX.png","inLanguage":"en","url":"https://sanity-nuxtui.vercel.app/_og/d/c_Page%2Ctitle_Visual%2BEditing%2Cdescription_~VHVybiBvbiB0aGUgbGl2ZSBwcmV2aWV3IGluIHRoZSBQcmVzZW50YXRpb24gdG9vbCwgbG9jYWxseSBhbmQgaW4gcHJvZHVjdGlvbi4%2Cheadline_Docs%2CsiteName_~U2FuaXR5IMOXIE51eHQgVUk%2Cp_Ii9kb2NzL3Zpc3VhbC1lZGl0aW5nIg%2Cs_sM6piyz9ALUg3cOX.png"}]}
```

## Sitemap

See the full [sitemap](https://sanity-nuxtui.vercel.app/sitemap.md) for all pages.
