vercel / next.js

The React Framework
https://nextjs.org
MIT License
127.23k stars 27.02k forks source link

context.res.setHeader not setting Cache-Control #62294

Open eloisetaylor5693 opened 9 months ago

eloisetaylor5693 commented 9 months ago

Link to the code that reproduces this issue

https://github.com/eloisetaylor5693/nextjs-set-cache-control

To Reproduce

export async function getServerSideProps(context: GetServerSidePropsContext) {
  context.res.setHeader(
    "Cache-Control",
    "public, s-maxage=300, stale-while-revalidate=600"
  );
  return {
    props: { title: "hello world" },
  };
}

results in the response header Cache-Control: no-store, must-revalidate

Current vs. Expected behavior

When testing in the browser, the response header doesn't include the cache control I set

Current: Cache-Control: no-store, must-revalidate Expected: Cache-Control: public, s-maxage=300, stale-while-revalidate=600

Provide environment information

Node: 20.10.0
npm: 10.2.3
Nextjs: canary

Which area(s) are affected? (Select all that apply)

Data fetching (gS(S)P, getInitialProps)

Which stage(s) are affected? (Select all that apply)

Other (Deployed)

Additional context

No response

victorcarvalhosp commented 3 months ago

Same problem here.

Edit by maintainer bot: Comment was automatically minimized because it was considered unhelpful. (If you think this was by mistake, let us know). Please only comment if it adds context to the issue. If you want to express that you have the same problem, use the upvote 👍 on the issue description or subscribe to the issue for updates. Thanks!

victorcarvalhosp commented 2 months ago

Exact same issue here. This is costing us a lot of money when Google crawls our website especially... Did you find some workaround for it?

eloisetaylor5693 commented 2 months ago

Hi @victorcarvalhosp, no I didn't. The only other options are SSG, implement your own caching of data eg with redis, or migrate to app router.

These aren't satisfactory workarounds since they are not necessarily appropriate for a page you want to cache depending on requirements

lhguerra commented 2 months ago

Migrating to app router might not help much. There are a lot of little things that can make a page dynamic and it won't cache at all. For instance, in v13 with pages router I could have a static page that accepted query strings (provided that those query strings are used only in client side), now I can't and the page must be dynamic, which in pages router with v13 I solved setting a cache header because I have Clouflare in front of Vercel. But with v14 it is impossible to set that header so dynamic pages can't be cached in Vercel and anywhere else!

victorcarvalhosp commented 2 months ago

Migrating to app router might not help much. There are a lot of little things that can make a page dynamic and it won't cache at all. For instance, in v13 with pages router I could have a static page that accepted query strings (provided that those query strings are used only in client side), now I can't and the page must be dynamic, which in pages router with v13 I solved setting a cache header because I have Clouflare in front of Vercel. But with v14 it is impossible to set that header so dynamic pages can't be cached in Vercel and anywhere else!

I had the exact same problem when I started migrating to the app router, so we decided not to proceed with that for now, as it would be a lot of work and we couldn't even be sure if it would cost less.