
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeThis is a common issue when using Sanity with Next.js 13's app directory! The problem is likely related to how you're configuring your Sanity client. Let me walk through the most common causes and solutions.
1. CORS Configuration (Most Likely for Client Components)
If you're using client.fetch() in a client component (marked with 'use client'), you need to add your localhost origin to your Sanity project's CORS settings. The reason jsonplaceholder works is because their API allows all origins, but Sanity requires explicit domain whitelisting for browser-based requests.
To fix this:
http://localhost:3000 (or whatever port you're using)This is covered in the CORS Origins documentation.
2. Dataset Privacy Settings
Your dataset might be set to private, which requires an API token for read access. Check your dataset settings at manage.sanity.io. If it's private, you'll need to:
import { createClient } from 'next-sanity'
export const client = createClient({
projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
dataset: process.env.NEXT_PUBLIC_SANITY_DATASET,
apiVersion: '2024-01-01',
useCdn: true,
token: process.env.SANITY_API_TOKEN, // Only needed if dataset is private
})Note: If your dataset is public (which is common for production websites), you don't need a token for read operations.
3. Incorrect Client Configuration
Make sure your client is properly configured. For Next.js 13+ app directory with Server Components (the default), you should use the next-sanity package:
npm i next-sanityThen create a sanity/client.ts file:
import { createClient } from 'next-sanity'
export const client = createClient({
projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID!,
dataset: process.env.NEXT_PUBLIC_SANITY_DATASET!,
apiVersion: '2024-01-01', // Use current date
useCdn: true, // Set to false if you want fresh data
})4. Using sanityFetch (Recommended)
For better caching and performance in Next.js 13+ app directory, consider using the sanityFetch helper from next-sanity instead of client.fetch(). It provides automatic cache configuration and works seamlessly with React Server Components:
import { sanityFetch } from './sanity/client'
const posts = await sanityFetch({
query: `*[_type == "post"]`,
tags: ['post'], // For cache revalidation
})NEXT_PUBLIC_SANITY_PROJECT_ID and NEXT_PUBLIC_SANITY_DATASET are correctly set*[_type == "post"][0..2] to isolate the issueThe key difference from jsonplaceholder is that Sanity has security measures in place - CORS restrictions for browser requests and optional authentication for private datasets. Once you configure these properly, client.fetch() will work just as reliably!
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store