# Combining Sanity CDN with the Next.js Cache https://www.sanity.io/learn/course/controlling-cached-content-in-next-js/combining-sanity-cdn-with-the-next-js-cache.md Implement Sanity Client in a way that compliments and leverages the Next.js cache with sensible defaults. Even if Next.js had no affordances for caching – or you use a framework with no in-built caching options – the Sanity CDN provides a performant way to query content. This lesson briefly summarizes how querying the correct endpoint in your Next.js application is situation-dependent. 1. See the documentation on the [API CDN](https://www.sanity.io/learn/content-lake/api-cdn) for more details ## Querying Sanity's API or CDN Your Sanity Client's `useCdn` setting determines whether your fetch request uses the CDN or the API. Depending on the context of your fetch, you may choose to query either one. ### Querying the Sanity API Querying the API is slower but guaranteed to be fresh. Your project's plan will have a lower allocation of API requests, so you should factor that into your usage. For these reasons you should only query the API (`useCdn: false`) when responses are infrequent and fast responses are not required. Examples include statically building pages ahead of time and performing incremental static revalidation or tag-based revalidation. ### Querying the Sanity CDN Querying the CDN is faster but not guaranteed to be fresh. The Sanity CDN's cache is flushed every time a publish mutation is performed on a dataset, so there may be a brief delay between the latest content being published and it being available from the CDN. Your project's plan will have a far higher allocation of CDN requests. You should query the CDN (`useCdn: true`) when responses are frequent and fast responses are desired. Examples include all situations other than those outlined in the previous situation where the API is preferred. This makes `useCdn: true` a sensible default. ### Overriding `useCdn` per-request Whatever your Sanity Client configuration, it can be overridden at the time of request using the `withConfig` method. In this section, you'll configure `generateStaticParams` to build individual post pages at build time, instead of at request time. 1. Read more about [`generateStaticParams` on the Next.js documentation](https://nextjs.org/docs/app/api-reference/functions/generate-static-params) 1. **Add** an exported `generateStaticParams` function to the dynamic route ```typescript:src/app/(frontend)/posts/[slug]/page.tsx // update your imports import { POST_QUERY, POSTS_SLUGS_QUERY } from "@/sanity/lib/queries"; // add this export export async function generateStaticParams() { const slugs = await client .withConfig({useCdn: false}) .fetch(POSTS_SLUGS_QUERY); return slugs } ``` When you next deploy your Next.js application, every individual post page will be created ahead of time, with guaranteed fresh data (fresh at the time it was deployed) fetched direct from the Sanity API. ## Sanity Client and Next.js cache configuration If you completed the previous lesson, you are relying on Sanity Live to perform caching and live updates. It is possible to manually set cache configuration options when performing fetches with the Sanity Client. ### `sanityFetch` helper function As detailed in the [next-sanity readme](https://github.com/sanity-io/next-sanity?tab=readme-ov-file#caching-and-revalidation), you may wish instead to create a helper function that wraps Sanity Client with caching configuration options. This `next` key in the Sanity Client configuration takes the same configuration options found in the Next.js documentation for [controlling how fetches are cached](https://nextjs.org/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#caching-data). 1. **Update** your `client.ts` file to include an exported helper function, `sanityFetch` ```typescript:src/sanity/lib/client.ts import {createClient, type QueryParams} from 'next-sanity' // other imports, client export // 👇 add this function export async function sanityFetch({ query, params = {}, revalidate = 60, // default revalidation time in seconds tags = [], }: { query: QueryString params?: QueryParams revalidate?: number | false tags?: string[] }) { return client.fetch(query, params, { next: { revalidate: tags.length ? false : revalidate, // for simple, time-based revalidation tags, // for tag-based revalidation }, }) } ``` The most important lines are highlighted above. By default this helper uses a 60 second revalidation—but will also accept tags for tag-based revalidation (covered in another lesson in this course). 1. **Update** your `/posts` route to use our own `sanityFetch` ```typescript:src/app/(frontend)/posts/page.tsx // update your imports import { sanityFetch } from "@/sanity/lib/client"; // update your fetch const posts = await sanityFetch({query: POSTS_QUERY}); ``` 1. **Update** your individual post route to do the same ```typescript:src/app/(frontend)/posts/[slug]/page.tsx // update your imports import { client, sanityFetch } from '@/sanity/lib/client' // update your fetch const post = await sanityFetch({ query: POST_QUERY, params, }) ``` 1. This route still uses `client` directly in the `generateStaticParams` export. It's acceptable to use the Sanity Client when the cache settings of a request are not essential. ### What about `options.cache`? Next.js will also accept options passed to the [Web Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API)'s cache, but incorrectly configuring both `next` and `cache` options can lead to errors. It's simplest to let `cache` fall back to its default setting and only focus on `next` in the following lessons. 1. See Next.js [documentation on how it handles fetch](https://nextjs.org/docs/app/api-reference/functions/fetch#fetchurl-options). ### Onward! With those changes made, you should see no change on your front end! However, you're in a much better place to implement time—and tag-based revalidation. Let's look a little more into time-based revalidation in the next lesson.