Issues with new document types not showing up in Next.js app using Sanity
This is a common frustration with Next.js 14 App Router and Sanity! The issue you're experiencing is actually caused by Next.js's aggressive data caching, not Sanity's CDN. Toggling useCdn seems to work temporarily because changing your client configuration forces Next.js to treat it as a "new" fetch, but the underlying caching problem remains.
The Root Cause: Next.js Data Cache
In Next.js App Router, all fetch requests (including those from client.fetch()) are automatically cached by Next.js's Data Cache. This is completely separate from Sanity's CDN caching. Even with useCdn: false, Next.js will still cache your query results indefinitely by default, which is why your new documents don't appear.
The Solution: Control Next.js Caching
You need to tell Next.js how to handle the cache for your Sanity queries. Here are your options:
Option 1: Disable caching during development
const data = await client.fetch(query, params, {
next: { revalidate: 0 } // Don't cache at all
})Option 2: Use cache: 'no-store'
const data = await client.fetch(query, params, {
cache: 'no-store' // Skip the cache entirely
})Option 3: Use the sanityFetch helper from next-sanity
The next-sanity package provides a sanityFetch helper that's designed specifically for App Router and handles caching configuration for you. You'll need to create this helper in your project:
// lib/sanity.fetch.ts
import { client } from './sanity.client'
export async function sanityFetch<QueryResponse>({
query,
params = {},
tags,
}: {
query: string
params?: any
tags?: string[]
}) {
return client.fetch<QueryResponse>(query, params, {
next: {
revalidate: 0, // For development
tags, // For production with tag-based revalidation
},
})
}Then use it in your components:
const posts = await sanityFetch({
query: POSTS_QUERY,
tags: ['post'],
})Another Potential Issue: Default Perspective
If you're using a recent API version (2025-02-19 or later), there's another possible culprit. The default perspective changed to published, which means you'll only see published documents by default.
If you're creating documents and they're staying in draft state (not clicking "Publish" in the Studio), they won't appear in your queries. To see drafts during development, configure your client:
const client = createClient({
// ... other config
perspective: 'previewDrafts', // Shows drafts with fallback to published
useCdn: false, // CDN doesn't support draft content
})Production Setup
For production, you'll want to use tag-based revalidation so your cache stays fresh when content changes. Combine sanityFetch with tags, then set up Sanity Functions to call Next.js's revalidateTag() when content changes. This gives you the performance benefits of caching without the staleness issues.
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.