Troubleshooting the use of CDN in a Sanity.io project

18 replies
Last updated: Sep 17, 2022
Hi all, I feel like I’m missing something super obvious regarding the CDN.
I’ve set
useCDN: true
and yet when I build, it still gives me the warning that I’m not using the CDN.
const options = {
	projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
	dataset: process.env.NEXT_PUBLIC_SANITY_DATASET_NAME,
	apiVersion: "2022-01-18", //date project was initialized
	useCDN: process.env.NEXT_PUBLIC_SANITY_DATASET_NAME === "production", <= results in true
};
When I inspect my site, I see the images have an address which includes
<http://cdn.sanity.io|cdn.sanity.io>
What am I missing?
AI Update

I can see the issue here! Based on the official API CDN documentation, the warning you're seeing is likely not related to authentication at all. Here's what's actually happening:

Your Images ARE Using the CDN

You correctly noticed that your images are loading from cdn.sanity.io - that's the Asset CDN, which always works through the CDN regardless of your client configuration.

The Build-Time Warning is Expected

When you run next build (or similar build commands), you're generating static content. During static builds, you should NOT use the CDN - you want the freshest data possible to build your pages. The warning is actually helpful here because it's reminding you that build-time queries should hit the live API, not the cached CDN.

The useCDN option controls whether your GROQ/GraphQL data queries use the cached API CDN (apicdn.sanity.io) or the live API (api.sanity.io).

About Authenticated Requests and the CDN

One important clarification: The API CDN documentation explicitly states that authenticated requests ARE cached on the CDN. They're just "segmented for each unique authentication token." So if you have a token in your client config, it will still use the CDN when useCDN: true is set.

Your Configuration is Actually Correct

Your setup looks good:

const options = {
  projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID,
  dataset: process.env.NEXT_PUBLIC_SANITY_DATASET_NAME,
  apiVersion: "2022-01-18",
  useCDN: process.env.NEXT_PUBLIC_SANITY_DATASET_NAME === "production", // ✅ Good
};

For production runtime: useCDN: true means browser requests will use the fast, cached CDN
For build time: The warning reminds you that builds should use fresh data

Note on the Option Name

The property name is useCdn (lowercase 'n'), not useCDN. While many JavaScript clients accept both due to case-insensitive handling, the canonical form is useCdn. If you're seeing a warning specifically about the casing, try changing:

useCDN: true  // might cause a warning

to:

useCdn: true  // canonical form

When You Actually See CDN Usage

The CDN is used for:

  • Client-side queries when useCdn: true
  • Image assets (always)
  • Runtime data fetching in browsers

The CDN is NOT used for:

  • Build-time queries (intentionally, to get fresh data)
  • Server-side rendering in some frameworks (depends on configuration)

Your setup is working correctly - the images are on the CDN, and your production client will use the API CDN for data queries at runtime. The build warning is just informing you that during the build process itself, you're hitting the live API for the freshest content.

What warning? 🙂
useCdn
tells the JS client to fetch using either the API (if false; api.sanity.io ) or the API CDN (if true; apicdn.sanity.io ). Images will always use the asset CDN regardless of the
useCdn
setting, at the slightly different URL
<http://cdn.sanity.io|cdn.sanity.io>
.
If it has
api
in the URL, it’s fetching a document. If it doesn’t, it’s fetching an asset.
user F
user A
any thoughts on how to resolve this info/warning note in my console?
As the error mentions, there’s a client configured somewhere where
useCdn
is not specified. If you change your ternary in
options
to a hard-coded true or false and the warning goes away, you’ll know it’s this config. If it doesn’t, it’s somewhere else.
Right, i hardcoded both of my files to
true
and i still got that error.
I would do a search for
client
(exclude node_modules) and see where there’s a client configured without
useCdn
.
I did a search for
client
and the only file that seemed relevant was this, so I added a
useCDN: true
property but it didn’t seem to impact the warning
From the looks of your first screenshot, it seems the warning is appearing when you run your front end app, so that’s where you’ll want to check for the use of
useCdn
. The most recent screenshot is in your studio directory.
Yeah, for sure. I’m actually working with a mono-repo so I did a search-all in VS Code looking for any mentions of
client
and all I got were the 3 files mentioned above and the groq API file. Do you potentially have any other ideas or tips?
Can you post
helpers/sanity.js
?
My guess is that your client in
helpers/sanity.js
is not configured explicitly with
useCdn
(side note: if not configured, it defaults to false). Typically, you’ll see something like this to configure the client in a helper file:

import sanityClient from '@sanity/client';

export const client = sanityClient({
  projectId: 'your-project-id',
  dataset: 'your-dataset',
  apiVersion: '2022-09-16', // use current UTC date - see "specifying API version"!
  token: 'sanity-auth-token', // or leave blank for unauthenticated usage
  useCdn: true, // `false` if you want to use the API
});
Then you’ll use
import { client } from 'helpers/sanity'
and can do
client.fetch()
.
Hey Geoff, actually my
/helpers/sanity.js
file is what I shared in my initial message
import sanityClient from '@sanity/client';

const options = {
    projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID, //points to the .env.local file
    dataset: process.env.NEXT_PUBLIC_SANITY_DATASET_NAME, //points to the .env.local file
    apiVersion: '2022-01-18', //date project was initialized
    useCDN: process.env.NEXT_PUBLIC_SANITY_DATASET_NAME === "production" // use false for dev or true for optimized speeds with cached data
};

export default sanityClient(options);
Then my
/studio/lib/isUniqueAcrossAllDocuments.js
file is this
import sanityClient from "part:@sanity/base/client";
const client = sanityClient.withConfig({apiVersion: '2022-01-18'})

// Note: this assumes that every document that has a slug field
// has it on the `slug` field at the root
export function isUniqueAcrossAllDocuments(slug, options) {
  const { document } = options;

  const id = document._id.replace(/^drafts\./, "");
  const params = {
    draft: `drafts.${id}`,
    published: id,
    slug,
  };

  const query = `!defined(*[
      !(_id in [$draft, $published]) && 
      slug.current == $slug
    ][0]._id)`;

  return client.fetch(query, params);
}
This is
helpers/generateRedirects.js

// Referenced in /next.config.js
const sanityClient = require("@sanity/client");

const options = {
	projectId: process.env.NEXT_PUBLIC_SANITY_PROJECT_ID, //points to the .env.local file
	dataset: process.env.NEXT_PUBLIC_SANITY_DATASET_NAME, //points to the .env.local file
	apiVersion: "2022-01-18", //date project was initialized
	useCDN: process.env.NEXT_PUBLIC_SANITY_DATASET_NAME === "production", // use false for dev or true for optimized speeds with cached data
};

const client = sanityClient(options);

const redirectsProjects = `
    redirectList[]{
        destination,
        source,
        permanent,
		basePath
    }
`;

async function generateRedirects() {
	const redirects = await client.fetch(
		`
        *[_type == "redirects"][0] {${redirectsProjects}}
        `
	);
	return redirects.redirectList || [];
}
module.exports = {generateRedirects};
And the last file which showed
client
was
helpers/api.js

import sanityClient from "helpers/sanity";
import imageUrlBuilder from "@sanity/image-url";

// Bunch of projections

export async function getBlogBySlug(slug) {
  const results = await sanityClient.fetch(
    `
      *[_type == "blog" && slug.current == $slug][0] {${singleBlogProjection}}
    `,
    { slug }
  );
  return results;
}

// Bunch more queries

const builder = imageUrlBuilder(sanityClient);
export function urlFor(source) {
  // This builder lets you provide additional parameters
  return builder.image(source);
}
So maybe I’m missing parameters on that last file,
helpers/api.js
?

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?