Issue with CORS when accessing dataset using @sanity/client in Gatsby app.
I can see exactly what's causing your CORS issue! The error message about Access-Control-Allow-Credentials being empty when it should be 'true' is a telltale sign.
The problem is that when you pass a token to the Sanity client, it automatically sets withCredentials: true on requests. This requires the "Allow credentials" checkbox to be enabled in your CORS configuration.
Here's how to fix it:
- Go to manage.sanity.io
- Select your project
- Navigate to Settings → API → CORS Origins
- Add
http://localhost:8000(your Gatsby dev server) - Most importantly: Check the "Allow credentials" checkbox for this origin
The origin you mentioned adding (https://<project-id>.api.sanity.io) is incorrect - that's the Sanity API itself, not your application's origin. You need to add the domain where your Gatsby app runs (http://localhost:8000 for development).
A couple other things to check:
- Make sure your environment variables are actually loading (add a
console.logto verify) - Your
useEffectis missing a dependency array, so it's running on every render. Add[]as the second argument to run it only once:
useEffect(() => {
const client = sanityClient({
projectId: process.env.GATSBY_SANITY_PROJECT_ID,
dataset: process.env.GATSBY_SANITY_DATASET,
token: process.env.SANITY_READ_TOKEN,
useCdn: false
})
client.fetch(`*[_type == "portfolioEntry"]{ title }`).then(res => {
console.log('res', res)
}).catch(err => {
console.error('F', err)
})
}, []) // <-- Add this dependency arrayWhy it works in Postman/Chromium: Those tools don't enforce CORS the same way browsers do with web applications, which is why you're only seeing the issue in your Gatsby app.
Once you enable "Allow credentials" for http://localhost:8000, your requests should work! When you deploy to production, remember to add your production domain with credentials enabled as well.
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.