vercel / next.js

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

Stale-while-revalidate is not working with getServerSideProps (Next js v13.5.6) #60938

Open Ruchika-saini opened 7 months ago

Ruchika-saini commented 7 months ago

Link to the code that reproduces this issue

https://github.com/Ruchika-saini/NextJs-swr/tree/main

To Reproduce

  1. Created a simple Next JS app with version 13.5.6.
  2. Created a home page, home page code :
const Home = () => {
  return (
    <div>hello</div>
  )
}
export async function getServerSideProps(ctx: any) {
// when tried accessing direct response through params, res is not accessible, able to access through context(ctx
  // res.setHeader(
  //   'Cache-Control',
  //   'public, s-maxage=10, stale-while-revalidate=59'
  // )
// Setting res headers through ctx
  ctx.res.setHeader(
    'Cache-Control',
    'public, s-maxage=10, stale-while-revalidate=59'
  )
  // Fetch data from an API
  const response = await fetch('https://tst30-ecms.stage.att.com/ui/global_all_cms_globalnav/web-components/2.0/preRender/consumer-lite/index.html');
  console.log('response', ctx.res);
  const posts = await response.text();
  // Return the data as props
  return {
    props: { posts },
  };
}
export default Home
  1. Build the app using "yarn build"
  2. Then "yarn start" to run in production mode.

Current vs. Expected behavior

Expected: When checking context.response on server(checking server logs), it should set the headers as coded ctx.res.setHeader( 'Cache-Control', 'public, s-maxage=10, stale-while-revalidate=59' )

Current: Headers are not set, there is no difference in the context.response headers. when analyzed further in next JS package(v13.5.6)), there is revalidate-headers.js file which is setting the headers based on the "options" values. In my case, when checked server c logs, "options" values are coming like this options { private: false, stateful: true, revalidate: 1 }

revalidate-nextjs

Coming back to "options" values options { private: false, stateful: true, revalidate: 1 }

"stateful" value needs to be false to enter into revalidate condition but it is coming as true. On checking further, how "stateful" value is set in next js package: "stateful" value is decided on based of SSG or not. stateful: !isSSG,

stateful is only going to be false when it's SSG (means page is using getStaticProps).

stateful-Nextjs

So, as documented here on Next JS website, that we can set stale-while-revalidate with getServerSide props as well is not going to work. https://nextjs.org/docs/pages/building-your-application/data-fetching/get-server-side-props#caching-with-server-side-rendering-ssr

I have tried to find any working example online as well or on Next JS website, couldn't find any who has successfully used this configuration with getServerSideProps.

Please help on resolving this and provide a working example of stale-while-revalidate with getServerSideProps.

Provide environment information

Window machine

$ next info

Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 10 Enterprise
Binaries:
  Node: 16.15.1
  npm: N/A
  Yarn: N/A
  pnpm: N/A
Relevant Packages:
  next: 13.5.6
  eslint-config-next: 12.1.6
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 4.9.5
Next.js Config:
  output: N/A

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

Data fetching (gS(S)P, getInitialProps)

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

next start (local)

Additional context

Tried this with Next js v12 and Next js v13.5.6 , no luck.

Ruchika-saini commented 7 months ago

Found this example: https://github.com/vercel/next.js/tree/canary/examples/ssr-caching

Tried this repo on local, and now I can see the response header setting the cache-control headers. But the page is not working as expected. Plus, I am running the app in production mode, first building the app, and then using "next start" to run the app. Using Next js v13.5.6.

Current Behavior: Res headers are there, but the time on the page(Time on the page) is getting updated on every request which should not be the case.

nextjs-res-headers

Expected Behaviour: Time on the page should not be updated on every request, it should serve the stale time value before 59s.

Please help with this, and mention the expected behavior in this case when caching is enabled in getServerSideProps.

ornakash commented 3 months ago

Same issue here. We set the exact same header but we don't even see the "stale-while-revalidate" in the response.