Replies: 1 comment
-
Hi @Winfle It looks like the author is running into a core behavior of the Next.js App Router: as soon as you call headers() or cookies() in a Server Component (RSC/SSR), the framework marks the page as “dynamic” and sends it with Cache-Control: private, no-store. That means:
At the moment, there isn’t a built-in way to override this and keep public caching with HTML variants. If you truly need HTML to be cached with a Vary, the only supported workarounds are: 1. Move the header/cookie handling to an API route
2. Use Edge Middleware for variant handling
3. Pre-generate variants as separate static paths
Unfortunately, there’s no public API in Next.js 13/14 that lets you call headers()/cookies() in a page and still tell the framework “this is public cacheable HTML with Vary” — the team would need to add an opt-in, like setCache({ mode: 'public', vary: ['accept-language'] }). If you want this to change, the best path is to:
|
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Summary
TL;DR: In Next.js, simply calling headers()/cookies() during page/component render automatically marks the page as dynamic and sends it with private/no-store. This breaks proper Vary handling (locale, customer-group, etc.): we want a public cache with variability, but end up with completely uncacheable HTML.
What’s wrong
End result: HTML is never cached – We’re forced to push the variability into JSON/API responses instead of the page itself.
Why this is a problem
We have a valid need for public cache with variability (e.g., Vary: accept-language, x-customer-group). This is a standard HTTP mechanism and CDNs like Fastly handle it perfectly.
Forced anti-pattern: Move header reading to an API route, set Vary there, and keep the HTML “static.” This adds complexity, extra requests, lack and doesn’t work well when the layout truly depends on the variant.
I'm looking for a solution to mark cache as public with having variants in place.
Thanks
Additional information
No response
Example
Minimal code:
Beta Was this translation helpful? Give feedback.
All reactions