Skip to content

fix(sanity): wrap sanityFetch in 'use cache' for cacheComponents compatibility - #208

Merged
arzafran merged 1 commit into
mainfrom
fix/sanity-cachetag-regression
Jun 8, 2026
Merged

fix(sanity): wrap sanityFetch in 'use cache' for cacheComponents compatibility#208
arzafran merged 1 commit into
mainfrom
fix/sanity-cachetag-regression

Conversation

@arzafran

@arzafran arzafran commented Jun 8, 2026

Copy link
Copy Markdown
Member

What this does

/sanity and /sanity/[slug] were crashing at runtime with:

cacheTag() can only be called inside a "use cache" function.

This fixes both pages so they render again.

Root cause

next.config.ts enables cacheComponents: true (added in 50485f8, "test experimental setting"). next-sanity's sanityFetch (from defineLive) calls cacheTag() internally to register the cache tag for live revalidation — and under Cache Components, cacheTag() is only legal inside a 'use cache' function. The Sanity example pages called sanityFetch outside any 'use cache' scope, so they threw.

This was latent on main — not introduced by a recent PR. Confirmed by reverting the cache() wrapper from #204 to the prior direct calls: the error persisted, so React cache() was never the cause (it is not a 'use cache' boundary).

Fix

Wrap each fetch in a 'use cache' function — next-sanity's intended pattern under Cache Components (a cached fetch whose cacheTag is revalidated by <SanityLive>). For [slug], the slug is passed as an argument so the cache keys per article. This supersedes #204's React cache() approach and still satisfies its goal: 'use cache' also dedupes across the page render and generateMetadata, so the same document is fetched once per request.

Test Plan

  • bun run check green — biome, tsgo --noEmit, 414 tests
  • Runtime (dev): /sanity and /sanity/lorem-ipsum render with no console errors (previously both threw cacheTag())
  • CI next build validates the prerender path under cacheComponents

next.config enables cacheComponents (since 50485f8). next-sanity's
sanityFetch calls cacheTag() internally, which is only legal inside a
'use cache' function, so /sanity and /sanity/[slug] crashed with
"cacheTag() can only be called inside a use cache function".

Wrap each fetch in a 'use cache' function — next-sanity's intended
pattern under Cache Components (cached fetch + tag-based revalidation via
SanityLive). This supersedes the React cache() wrapper from #204 (which
was not a 'use cache' scope and did not fix the crash); 'use cache' also
dedupes across the page render and generateMetadata, so the original
dedup goal is still met.

Verified in-browser: /sanity and /sanity/lorem-ipsum render with no
console errors.
@arzafran
arzafran merged commit 96de662 into main Jun 8, 2026
8 checks passed
arzafran added a commit that referenced this pull request Jun 8, 2026
- CHANGELOG [Unreleased]: log the boundary validation + cart-type work
  (#198), the effort:low fixes (#205), the WebGL cleanup (#199/#206),
  lenis-prevent (#207), the Sanity 'use cache' fix (#208), and react-scan
  as an Orchestra toggle (#209).
- components/README: drop the deleted dropdown/ row (now Base UI Select).
- lib/dev/README: add the 🧊 webgl and 🔬 react-scan toggles to the
  Orchestra table; note react-scan is opt-in and how it relates to Stats.
- sanity/README: show the 'use cache' fetch pattern required under
  cacheComponents (bare sanityFetch throws cacheTag()).
arzafran added a commit that referenced this pull request Jun 9, 2026
- AGENTS.md: document the 'use cache' rule for cacheTag()-calling fetches
  (the #208 crash) and parseApiResponse boundary response-validation (#198)
- shopify README: updateItemQuantity/removeItem now take client-held lineId;
  note GraphQL envelope validation
- webgl README: flowmap/fluid sims are opt-in (#199, #206)
- biome-custom-rules: flag the cited dropdown example as since-removed (#202)
@arzafran
arzafran deleted the fix/sanity-cachetag-regression branch June 22, 2026 14:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant