-
-
Notifications
You must be signed in to change notification settings - Fork 780
Description
Describe the feature
defineCachedEventHandler currently couples Nitro server storage caching with response cache headers by automatically emitting Cache-Control based on maxAge.
In some setups, this makes it impossible to treat Nitro cache as server-only, because browsers or CDNs may cache the response and stop requests from reaching the server entirely. Once that happens, shouldBypassCache / shouldInvalidateCache are never evaluated, and server-side invalidation logic becomes ineffective.
CDN context
In practice, some CDNs (e.g. Cloudflare) do not reliably honor Vary when constructing cache keys (see: https://developers.cloudflare.com/cache/concepts/cache-control/), which means varies may not work as expected on the client/edge even if Nitro emits it correctly.
As a result, response caching can escape Nitro’s control even when varies is configured.
Reproduction
export default defineCachedEventHandler(async () => {
return { ts: Date.now() }
}, {
maxAge: 60,
varies: ['x-foo']
})Observed:
- Nitro caches correctly in server storage
Cache-Controlis sent to the client- Browser/CDN may cache and never revalidate
- Subsequent requests may never reach Nitro
Expected (for some use cases):
- Server storage cache is used
- Client is not instructed to cache
- Cache correctness and invalidation remain server-controlled
Workaround
Using defineCachedFunction instead of defineCachedEventHandler avoids emitting response cache headers and works as a server-only cache, but it loses the event handler semantics and is not always a good fit.
Proposed solution
Allow defineCachedEventHandler to opt out of emitting cache-related response headers, while still using server storage caching.
Example API shapes:
defineCachedEventHandler(handler, {
maxAge: 60,
sendHeaders: false
})or
defineCachedEventHandler(handler, {
maxAge: 60,
cacheControl: false
})Default behavior would remain unchanged.
Why this matters
- Server-side caching and client/CDN caching are separate concerns in real deployments
- External caches are common and not always fully spec-compliant
- Nitro should not lose control of its cache invalidation logic due to response headers
Related: #2738
English is not my first language, and I used AI to help refine the wording of this issue.
Additional information
- Would you be willing to help implement this feature?