Content editors often complain: to fix a paragraph, you need to open Sanity Studio, find the right field, save, switch to the website, and refresh the page. Loss of context and time. We solve this problem with Sanity Visual Editing and Presentation Tool—a mode where edits are made directly on the website page.
Sanity Visual Editing turns the website into an interactive interface for editors: a click on text opens the corresponding field in Sanity Studio, and the change applies instantly with live preview. This is not just preview—it's full interactive editing. In our estimation, this setup reduces content editing time by 60%, and for multi-author projects, team productivity increases by 30-40%.
How Visual Editing Speeds Up Editor Work?
At the core of the technology are Content Source Maps. When you request data through next-sanity with the stega: true flag, Sanity injects invisible metadata into strings. They indicate which document and field the text comes from. Visual Editing reads these markers when clicking on an element and opens the corresponding field in Studio. The editor doesn't need to search for a section or document—everything happens in the context of the page.
This approach is faster than classic Preview, which requires a full page reload and manual field search. Visual Editing works via iframe and WebSocket—changes appear in 200-300 ms. We have used this setup in more than 10 projects, and editing time decreased by 60% on average. According to the Sanity Visual Editing documentation, Content Source Maps are the key mechanism for linking data with the visual editor.
Why Content Source Maps Are the Foundation of Visual Editing?
Content Source Maps add metadata to the API response about the origin of each field. When stega is enabled, content strings contain invisible characters with information about the schema, document, and path. Visual Editing reads these markers when clicking on an element and knows exactly which field to open in Studio. This eliminates manual search—the editor clicks on text on the page and immediately lands in the correct field. Without Content Source Maps, Visual Editing would be just a preview without interactivity.
More about stega configuration
For Visual Editing to work, stega must be enabled on the client. Without it, the editor can only view but not click on elements. Here is an example configuration:
// lib/sanity/client.ts import { createClient } from 'next-sanity' const client = createClient({ projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!, dataset: 'production', apiVersion: '2024-01-01', useCdn: false, stega: { enabled: true, studioUrl: process.env.NEXT_PUBLIC_SANITY_STUDIO_URL!, }, }) For live preview with WebSocket we use defineLive. This package connects useOptimistic and automatically updates data when changed in Studio. The editor sees edits in real time without reloading.
Step 1: Setting up Studio
Install the @sanity/presentation plugin and configure previewUrl specifying the origin and routes for Draft Mode. Example configuration:
// sanity.config.ts import { presentationTool } from '@sanity/presentation' export default defineConfig({ plugins: [ structureTool(), presentationTool({ previewUrl: { previewMode: { enable: '/api/draft-mode/enable', disable: '/api/draft-mode/disable', }, origin: process.env.SANITY_STUDIO_PREVIEW_URL || 'http://localhost:3000', }, }), ], }) Step 2: Implementing Draft Mode in Next.js
Create API routes /api/draft-mode/enable and /api/draft-mode/disable, using validatePreviewUrl to verify the secret token.
// app/api/draft-mode/enable/route.ts import { validatePreviewUrl } from '@sanity/preview-url-secret' import { client } from '@/lib/sanity/client' import { draftMode } from 'next/headers' import { redirect } from 'next/navigation' export async function GET(req: Request) { const { isValid, redirectTo = '/' } = await validatePreviewUrl( client.withConfig({ token: process.env.SANITY_API_TOKEN! }), req.url ) if (!isValid) { return new Response('Invalid secret', { status: 401 }) } draftMode().enable() redirect(redirectTo) } // app/api/draft-mode/disable/route.ts import { draftMode } from 'next/headers' import { NextRequest, NextResponse } from 'next/server' export async function GET(req: NextRequest) { draftMode().disable() return NextResponse.redirect(new URL('/', req.url)) } Step 3: Connecting the Client
Add VisualEditingProvider to the layout, configure sanityFetch and SanityLive for live updates.
What's Included in the Setup?
We provide a full cycle of work—from audit to deployment with editor training:
| Stage | What We Do | Result |
|---|---|---|
| Project audit | Check schema, routing, package versions | Report with recommendations |
| Design | Determine where Visual Editing is needed, which fields | Integration plan |
| Studio setup | Install Presentation Tool, configure preview | Working editing interface |
| Frontend integration | Add Draft Mode, VisualEditingProvider, live preview | Interactive preview |
| Testing | Check all scenarios: guest, editor, admin | Checklist passed |
| Deployment | Configure demo server, CI/CD, environment variables | Working production |
| Training | Documentation and 1-2 sessions with editors | Team ready to work |
Comparison with alternatives:
| Criterion | Sanity Visual Editing | Regular Preview |
|---|---|---|
| Response time | 200-300 ms (WebSocket) | 2-3 seconds (reload) |
| Context | Editor sees site, clicks on element | Need to find field in Studio |
| Depth of edits | Any element, including images | Only text or blocks |
| Change support | Real-time via useOptimistic | Requires manual refresh |
Timelines and Experience
Setting up Visual Editing with Presentation Tool and Draft Mode takes from 1 to 2 days for a typical project. For complex projects, the timeline may extend to 3–5 days. The cost is calculated individually—we assess your project in one working day.
Order Visual Editing setup from us—we guarantee correct integration thanks to 10+ years of experience and 50+ successful CMS integrations. Just contact us via messenger or email—we will send an implementation example for your project.







