Issue with preview content not updating after publishing in Sanity Studio and Next.js app.

6 replies
Last updated: Dec 20, 2022
Hello,
I am using v2 in sanity studio. I am not able to see the preview content in local too. I have sanity studio and next js(frontend) app in two different repositories. I am following docs -


https://www.sanity.io/guides/nextjs-live-preview

https://www.sanity.io/docs/preview-content-on-site Video is attached. Thanks in advance.
AI Update

I can see you're trying to set up preview functionality with Sanity Studio and Next.js in separate repositories, following the nextjs-live-preview guide and the preview-content-on-site docs.

First, let me clarify something important: both guides you're following are for Sanity Studio v3 with the Presentation tool. When you mentioned "using v2 in sanity studio," I want to make sure we're on the same page about your actual Studio version.

Check Your Studio Version

Run this command in your Studio repository to confirm which version you have:

npm list sanity

If you see sanity@2.x.x, you have Studio v2. If you see sanity@3.x.x or higher, you have Studio v3.

Studio v2 does not have the Presentation tool that those guides describe. The Visual Editing workflow with real-time preview, click-to-edit overlays, and the embedded iframe preview requires Studio v3.

If You Have Studio v3

Since you can't see preview content locally, here are the most common issues with separate repository setups:

1. CORS Configuration

With Studio and Next.js on different ports/domains, you need to configure CORS:

  • Go to manage.sanity.io
  • Select your project → API tab
  • Under CORS Origins, add your local Next.js URL (e.g., http://localhost:3000)
  • Enable "Allow credentials"

2. Draft Mode Not Activating

The Presentation tool needs to activate draft mode in your Next.js app. Check:

In your Studio's sanity.config.ts:

import { presentationTool } from 'sanity/presentation'

export default defineConfig({
  // ... other config
  plugins: [
    presentationTool({
      previewUrl: {
        draftMode: {
          enable: '/api/draft', // This should match your Next.js API route
        },
      },
    }),
  ],
})

In your Next.js app, you need an API route (e.g., /pages/api/draft.ts for Pages Router):

import { validatePreviewUrl } from '@sanity/preview-url-secret'
import type { NextApiRequest, NextApiResponse } from 'next'
import { createClient } from 'next-sanity'

const client = createClient({
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET!,
  apiVersion: '2024-01-01',
  useCdn: false,
  token: process.env.SANITY_API_READ_TOKEN!,
})

export default async function handle(req: NextApiRequest, res: NextApiResponse) {
  const { isValid, redirectTo = '/' } = await validatePreviewUrl(client, req.url!)
  
  if (!isValid) {
    return res.status(401).send('Invalid secret')
  }
  
  res.setDraftMode({ enable: true })
  res.writeHead(307, { Location: redirectTo })
  res.end()
}

3. Missing Token

You need a viewer token for stega encoding to work:

  • Create a token with Viewer permissions in your project settings
  • Add it to your .env.local file as SANITY_API_READ_TOKEN
  • Configure your Sanity client to use it when draft mode is active

4. Client Configuration

Your Sanity client needs to be configured for preview with the previewDrafts perspective and stega encoding:

import { createClient } from '@sanity/client'

export function getClient(previewToken?: string) {
  return createClient({
    projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,
    dataset: process.env.NEXT_PUBLIC_SANITY_DATASET!,
    apiVersion: '2024-01-01',
    useCdn: !previewToken,
    perspective: previewToken ? 'previewDrafts' : 'published',
    stega: {
      enabled: previewToken ? true : false,
      studioUrl: 'http://localhost:3333', // Your Studio URL
    },
    token: previewToken,
  })
}

5. Live Query Setup

You need to use useLiveQuery from next-sanity/preview to see real-time updates:

import { useLiveQuery } from 'next-sanity/preview'

export default function PostPreview({ post, params }) {
  const [data] = useLiveQuery(post, POST_QUERY, params)
  return <Post post={data} />
}

If You Have Studio v2

If you confirmed you have Studio v2, you'll need to upgrade to Studio v3 to use those guides. Follow the Studio v3 migration guide. Studio v2 is in maintenance mode and the modern Visual Editing features simply don't exist in v2.

Debugging Steps

Without seeing the video you mentioned, here's how to diagnose the issue:

  1. Check the browser console in both Studio and Next.js for errors
  2. Verify draft mode is active - add a banner in your Next.js app that shows when draft mode is enabled
  3. Check Network tab - when you open Presentation, does it successfully call your /api/draft route?
  4. Test the preview URL directly - try visiting http://localhost:3000/api/draft?slug=/your-page manually

The most common issue with separate repositories is the draft mode not activating due to CORS, missing tokens, or incorrect API route configuration.

If you can share specific error messages from your console or clarify your Studio version, I can provide more targeted help!

do you have some form of revalidating the content you fetch from sanity? Having the same problem with live editing when i revalidate the content.
Hey
user U
,
No there is no revalidation in content. I just followed doc -
https://www.sanity.io/blog/build-your-own-blog-with-sanity-and-next-js .
Then I separated studio and FE app in different repos and deployed with vercel.
Would the preview update when you press publish?
I tried with changing title and check preview. Then I tried with update the title and click on publish. Again I have checked preview and i have not got any updates.
hey,
Above issue is solved now. I have not added FE code and I am expecting preview to run.

Now I get another issue to tackle in sanity. I am following
https://www.sanity.io/guides/nextjs-live-preview#284b10a97285 .
Now I am getting error in following line -

if (preview) {
return data.find((item) =&gt; item._id.startsWith(
drafts
)) || data[0]; }

I am getting following json in
data

 [
  {
    authorImage: { _type: 'image', asset: [Object] },
    body: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ],
    categories: [ 'Web', 'Frontend' ],
    name: 'Saurin Thakkar',
    title: 'My very first blog post[New Content Coming soon] sodium'
  },
  {
    authorImage: { _type: 'image', asset: [Object] },
    body: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ],
    categories: [ 'Web', 'Frontend' ],
    name: 'Saurin Thakkar',
    title: 'My very first blog post[New Content Coming soon] sew'
  }
] {
  authorImage: {
    _type: 'image',
    asset: {
      _ref: 'image-1c110ad195abfc4f7c43a7cbe49cbcac178027f1-8000x4910-jpg',
      _type: 'reference'
    }
  },
  body: [
    {
      _key: '0d2d679aa95f',
      _type: 'block',
      children: [Array],
      markDefs: [],
      style: 'h1'
    },
    {
      _key: '9a37a88637a5',
      _type: 'block',
      children: [Array],
      markDefs: [],
      style: 'normal'
    },
    {
      _key: 'fce417774166',
      _type: 'block',
      children: [Array],
      markDefs: [],
      style: 'normal'
    },
    { _key: '952b53df63f0', _type: 'image', asset: [Object] },
    {
      _key: '6034efcf3aa3',
      _type: 'block',
      children: [Array],
      markDefs: [],
      style: 'normal'
    },
    {
      _key: '3649cbf0b7d7',
      _type: 'block',
      children: [Array],
      level: 1,
      listItem: 'bullet',
      markDefs: [],
      style: 'normal'
    },
    {
      _key: '6e550197e84e',
      _type: 'block',
      children: [Array],
      level: 1,
      listItem: 'bullet',
      markDefs: [],
      style: 'normal'
    }
  ],
  categories: [ 'Web', 'Frontend' ],
  name: 'Saurin Thakkar',
  title: 'My very first blog post[New Content Coming soon] sodium'
}
There is no
item_id
in whole json to return object. So can anybody help give some advice for same.
Thanks
help
Thanks for sharing your solution
user D
!

Sanity – Build the way you think, not the way your CMS thinks

Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.

Was this answer helpful?