Sanity preview mode not returning draft posts in Next.js 13 app directory

14 replies
Last updated: Nov 29, 2025
Hello everyone – hoping someone might be able to help me.
I've recently setup Sanity preview mode with Next.js 13 (app directory). The query I'm using the fetch my post in preview mode looks like this:


*[_type == "post" && slug.current == $slug][0]{ ..., authors[]->, categories[]->]
This however, doesn't bring back any posts that are in draft mode, only posts that are published are returned, which seems to defeat the purpose. I couldn't find anything in the docs that explains how to include draft posts in the response, so I'm wondering if I'm going about this in the right way. Should it be the case, instead, that posts have a field called, say 'publishedAt', which is used to filter out posts on the main site that haven't yet been published?

Any pointers would be greatly appreciated.
AI Update

You're on the right track! The issue is that you need to configure your Sanity client to use the correct perspective to see draft documents. By default, Sanity clients use the published perspective (especially in newer API versions), which only returns published documents.

To see drafts in your preview mode, you need to set the perspective to previewDrafts when creating your Sanity client. This perspective will prioritize draft versions over published ones when both exist, which is exactly what you want for preview functionality.

Here's how to set it up with Next.js 13 app router:

import { createClient } from 'next-sanity'

// Client for preview mode
export const previewClient = createClient({
  projectId: 'your-project-id',
  dataset: 'your-dataset',
  apiVersion: '2024-01-01',
  useCdn: false, // Important: disable CDN for preview
  perspective: 'previewDrafts', // This is the key setting
  token: process.env.SANITY_API_READ_TOKEN, // Required for drafts
})

// Regular client for production
export const client = createClient({
  projectId: 'your-project-id',
  dataset: 'your-dataset',
  apiVersion: '2024-01-01',
  useCdn: true,
  perspective: 'published',
})

Important notes:

  1. Token required: To access draft documents, you need to provide an API token with read permissions. Draft content is private and requires authentication.

  2. Disable CDN: Set useCdn: false for preview clients since draft content shouldn't be cached.

  3. Perspective options: As explained in the Sanity perspectives documentation, there are several perspectives:

    • published - Only published documents
    • previewDrafts - Prioritizes drafts over published (perfect for preview)
    • raw - Returns both drafts and published (can cause duplicates)

Your GROQ query itself is fine - you don't need to modify it. The perspective setting handles filtering draft vs published documents at the client level.

When implementing Draft Mode with Next.js, make sure to use the preview client (with previewDrafts perspective) when Draft Mode is active, and the regular client (with published perspective) for normal page views.

To answer your other question: while having a publishedAt field can be useful for scheduling or filtering, it's not necessary for basic draft/published workflows. Sanity's built-in draft system (where drafts are prefixed with drafts. in their _id) combined with perspectives is the standard approach for handling unpublished content.

Show original thread
14 replies

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?