Next.js - Which Data Fetching Method to Use

2 replies
Last updated: Apr 20, 2021
I see that sanity.io is built with Next JS. Which data fetching method are you guys are using? Because all the three methods have limitations of their own
AI Update

Great question! You're right that each Next.js data fetching method has trade-offs. The Sanity.io marketing site uses a sophisticated combination of approaches, primarily leveraging Incremental Static Regeneration (ISR) with tag-based revalidation via revalidateTag.

Primary Strategy: ISR + Tag-Based Revalidation

The Sanity team uses the Next.js App Router with React Server Components, which allows data fetching directly in components without getStaticProps or getServerSideProps. The key is controlling cache behavior through:

1. Tag-based cache invalidation - This is the secret sauce. When fetching content, they tag queries with document types:

const posts = await sanityFetch({
  query: POSTS_QUERY,
  tags: ['post', 'author', 'category'],
})

Then when content changes in Sanity, they use revalidateTag() to surgically invalidate only the affected cached content - not the entire site. This solves ISR's biggest limitation: you don't need to wait for a time-based revalidation period or rebuild everything.

2. Granular control - For individual pages, they can even tag with specific identifiers:

tags: [`post:${params.slug}`, 'author', 'category']

This means editing one blog post only revalidates that specific page, not all blog posts.

Why This Works Better

This approach combines the best of all worlds:

  • SSG benefits: Fast page loads, CDN-cacheable
  • SSR freshness: Content updates propagate immediately via tag-based revalidation
  • No ISR staleness: You're not stuck with stale content until the next revalidation interval
  • Efficient: Only affected pages rebuild, not the entire site

Tag-based revalidation is especially powerful for connected content. If a blog post references authors and categories, you can invalidate all three document types when any changes, ensuring consistency across your entire site.

Modern Alternative: Live Content API

For new projects, Sanity now offers the Live Content API (GA as of March 2025), which handles fetching, rendering, caching, and invalidation automatically without manual cache management. It provides real-time updates without websockets and works seamlessly with Next.js App Router through the next-sanity toolkit.

The Live Content API essentially makes your content "live by default" - when editors publish changes in Sanity Studio, those updates appear instantly across all your applications without any cache invalidation code. This eliminates the complexity of managing revalidateTag calls and webhook configurations entirely.

Recommendation

For most production Next.js + Sanity sites:

  • Use ISR + tag-based revalidation if you need precise control over cache behavior and are comfortable with the setup
  • Use the Live Content API if you want the simplest implementation with automatic real-time updates

Both approaches are production-ready and used at scale. The combination of ISR + tag-based revalidation remains popular because it gives you fine-grained control, while the Live Content API represents the future direction with less infrastructure to manage.

Hi
user R
, we're using a combination of all three on sanity.io depending on the needs of each page. Where we use
getServerSideProps
, we set custom cache headers to not have to compute results on each request. And indeed, we're hosting on Vercel, although the Swag Store is hosted on Netlify.
user M
Are there any docs/tutorials from where I can learn for setting custom cache headers

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?