next.js
next.js copied to clipboard
ISR cache issue on root page when using optional catch all routes
Verify canary release
- [X] I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System: Platform: darwin Arch: arm64 Version: Darwin Kernel Version 21.5.0: Tue Apr 26 21:08:37 PDT 2022; root:xnu-8020.121.3~4/RELEASE_ARM64_T6000 Binaries: Node: 17.2.0 npm: 8.1.4 Yarn: N/A pnpm: N/A Relevant packages: next: 12.2.5-canary.4 eslint-config-next: 12.2.4 react: 18.2.0 react-dom: 18.2.0
What browser are you using? (if relevant)
not relevant
How are you deploying your application? (if relevant)
not relevant
Describe the Bug
The bug happens when using ISR with an optional catch all route at the root of the pages
dir, like pages/[[...slug]].tsx
, and when no root path is returned from getStaticPaths
.
export const getStaticPaths: GetStaticPaths = async () => {
return {
paths: [],
fallback: 'blocking',
};
};
When hitting the root route http://localhost:3000/
the Cache-Control
Response Header only shows up on the initial request, on all subsequent requests, the Cache-Control
Response Header is gone, and the Response Header now always has a x-nextjs-cache: STALE
.
The issue only happens on the root page, using any other url path, like http://localhost:3000/foobar
works as expected.
This issue appears to have started with v12.2.1 and is not happening in v12.1.6
Expected Behavior
The Cache-Control
Response Header should be present on every request for the root page.
Link to reproduction
https://github.com/scpaye506/isr-cache-issue
To Reproduce
Pull down reproduction repo.
-
npm install
-
npm run build
-
npm run start
- open browser dev tools and then visit http://localhost:3000/ and inspect the response headers, if this is the first visit to the page you should see the
Cache-Control: s-maxage=10, stale-while-revalidate
header - refresh the page and inspect response headers again and the
Cache-Control
header is gone and the page is being regenerated on every request going forward.
I also ran into this issue recently, as a temporary fix you can instead define a catch all route with a single bracket, along with a predefined route for the index page reusing your exports from the dynamic route.
For example instead of using pages/[[...slug]].tsx
├── pages
│ └── [[...slug]].tsx
Use
├── pages
│ ├── [...slug].tsx
│ └── index.tsx
And populate index.tsx to export the same methods from your catch all route:
// pages/index.tsx
export { default, getStaticProps } from './[...slug]';
Obviously not ideal but hopefully helps others in the meantime.
Hey I think this lead me to solving the same issue, I didn't realize we weren't generating the homepage in getStaticPaths - seemingly fixes things when I do this.
For me, this was only an issue when using output: 'standalone',
, not when running next start
. I was having this issue on next 13.5.6.
@scpaye506 Thank you for this issue, I was tearing my hair out.