Empty Arrays from Sanity Client Despite Correct Setup and CORS Config

11 replies
Last updated: Sep 9, 2022
I'm having a hard time connecting my project to my backend. I put content into my Sanity backend, created a token, and added my application localhost to the CORS. When I inspect my application terminal, I have arrays, but they're empty. I'm also getting an uncaught error. I don't believe I set up my client page wrong. I set the token as an environmental paramotor
import sanityClient from '@sanity/client';

export const client = sanityClient({
  projectId: 'lj43vq66',
  dataset: 'production',
  apiVersion: '2022-03-10',
  useCdn: false,
  token: process.env.NEXT_PUBLIC_SANITY_TOKEN,
});

AI Update

Looking at your code, I can help you troubleshoot the empty arrays and connection issues. Let me walk through the most likely causes and solutions:

Your Client Configuration

Your setup looks mostly correct, but there are a few things to check:

import sanityClient from '@sanity/client';

export const client = sanityClient({
  projectId: 'lj43vq66',
  dataset: 'production',
  apiVersion: '2022-03-10',
  useCdn: false,
  token: process.env.NEXT_PUBLIC_SANITY_TOKEN,
});

Note on the package: @sanity/client is the correct official JavaScript client package for Sanity. You can also use the named export createClient instead of the default export:

import { createClient } from '@sanity/client';

export const client = createClient({
  // ... your config
});

Both approaches work fine with the official package.

Most Likely Issues

1. You're Only Getting Draft Documents

This is the most common reason for empty arrays. When you create content in Sanity Studio, it's initially saved as a draft with an ID like drafts.my-document-id. Your query might be filtering these out if you're only looking for published documents.

To check if you have any documents at all:

client.fetch('*[_type == "yourDocumentType"]')
  .then(data => console.log('All docs (including drafts):', data))

To explicitly query drafts:

client.fetch('*[_id in path("drafts.**")]')
  .then(data => console.log('Draft documents:', data))

Solution: Either publish your documents in Sanity Studio (look for the "Publish" button), or use the previewDrafts perspective which prioritizes drafts over published versions.

2. Perspective Configuration

As of the 2025-02-19 API version, the default perspective changed to published (which excludes drafts). Since you're using an older API version (2022-03-10), you're getting the raw perspective by default, but it's worth being explicit:

export const client = createClient({
  projectId: 'lj43vq66',
  dataset: 'production',
  apiVersion: '2022-03-10',
  useCdn: false,
  perspective: 'previewDrafts', // This will show drafts if they exist
  token: process.env.NEXT_PUBLIC_SANITY_TOKEN,
});

3. Token Usage (Important!)

For reading published content, you don't need a token at all. Tokens are only required for:

  • Writing/mutating data
  • Reading draft content (if your dataset is private)
  • Accessing private datasets

If you're just fetching published content, remove the token line entirely. This also means you don't need NEXT_PUBLIC_ prefix (which exposes it client-side).

4. Environment Variable Issues

If you do need the token, check:

  • Your .env.local file has: NEXT_PUBLIC_SANITY_TOKEN=your_token_here (no quotes, no spaces)
  • You restarted your dev server after adding the environment variable
  • The token has the correct permissions in your Sanity project settings (Manage → API → Tokens)

You mentioned "environmental paramotor" (parameter?) - make sure there are no typos in your .env.local file.

Debugging Steps

1. Verify your connection and count documents:

client.fetch('count(*)')
  .then(count => console.log('Total documents:', count))
  .catch(err => console.error('Connection error:', err));

2. Check what document types exist:

client.fetch('array::unique(*[]._type)')
  .then(types => console.log('Document types:', types))
  .catch(err => console.error('Error:', err));

3. Look at actual document IDs:

client.fetch('*[0...5]{_id, _type}')
  .then(docs => console.log('Sample documents:', docs))
  .catch(err => console.error('Error:', err));

About CORS

Your CORS configuration (adding localhost) is correct for development. CORS errors would show up in the browser console as "blocked by CORS policy" messages, not as empty arrays, so that's probably not your issue.

Here's a cleaned-up version that should work:

import { createClient } from '@sanity/client';

export const client = createClient({
  projectId: 'lj43vq66',
  dataset: 'production',
  apiVersion: '2024-01-01', // Use a more recent date
  useCdn: true, // Enable for better performance
  perspective: 'previewDrafts', // Shows drafts in development
  // Only add token if you need to write data or read private content
});

The empty arrays suggest your connection is working, but your queries aren't finding the documents you expect. Most likely, your content is in draft state and needs to be published, or your query is filtering by the wrong _type. Check the browser console for the specific uncaught error message - that will tell us exactly what's failing.

Show original thread
11 replies
Hi User. Perhaps double-check that the dataset you’ve configured in your client is the one you want.
Like making sure the token is for the right project?
Rather, that
production
is the correct dataset.
I do have two datsets in the project.
production
&
sanity-back
. Sanity-back is set to private. If I switched datasets, would I need to change that?
The one you specify when you configure
client
is what it will try to source from. If
sanity-back
is the one you’re using, you’d want to change your config to
dataset: 'sanity-back'
.
Apparently I was working in the wrong dataset. Is there a simple way to change the data over
To actually move data, you could follow either of the methods here . If you want to source from the other dataset, you can change your reference to it on your front end (i.e., as we discussed) and in your sanity.json file in your studio.
I'm on it. Thank you!
Side note, you might want to avoid making your token public to your client-side code since it comes with elevated privileges. If you’re using Next.js, the typical recommendation is to use the client on the server or at build time but not in the frontend.
I thought that by setting it as an environmental I'd be safe. My front end is set up in three different folders. If I define my token outside of those folders in the root. is that okay?
Well “safe” is a relative word. Making it an environment variable is a good idea in theory, but considering environment variables prefixed with
NEXT_PUBLIC_
are exposed in JavaScript bundles, the entire notion of safety goes out the window. 🙂
So you can still use an environment variable, this is good. Just remove the prefix so it never makes its way to the client. This way you use it only on the server or at build time, where it is in fact safe.

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?