-
Notifications
You must be signed in to change notification settings - Fork 27k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SSG pages re-render if middleware is being used #38267
Comments
I think my issue is similar to this. CMIIW if it's not, I will create a new issue. However for me, the second render is going to my catch-all route, which is not the intended route I need to land on. I have prepared an env to reproduce this;
Link to reproduction [EDIT]:
nextjs-poc-38267_1.mp4 |
@chozzz Yes exactly! On my main project that I noticed this issue, my app structure is as below:
What I noticed is that the main issue is pages are rendering twice, but at the same time, when you render a dynamic-route which has a catch-all-route on its parent (like dynamic routes in /blog/[uri].js), the dynamic-route page loads the first time using its own component, on second time, it re-render using the parent catch-all route also without passing the props. What actually happens on those dynamic-route pages, is that the page loads completely without any issue (loads all content properly), but on re-render (that should not happen at the first place), it uses the catch-all route component without passing the props and the page becomes empty or returns this error based on whether accurate data validation is done or not:
I wasn't able to re-produce it on the repo that I made to report this bug because I thought the problem is with the re-render thing, but I can confirm that the same thing happens for me too. I hope that helps. |
Agree, same with my #38273 issue |
Confirming, same here. It occurs in both production and development mode. I use getInitialProps in custom app and the devtools react profiler reported that the cause of the re-rendering was the change of props in _app.tsx . Disabling the middleware fixes the double render... |
I think this may be the cause of the performance issue I filed earlier: |
@willemliufdmg IMHO, This issue could surely affect the performance but I think the one that you mentioned in #38235 could be different since it affects the server response time and TTFB. This one happens after the page is loaded. [EDIT] I think it's more relevant to #38171 |
This should be addressed with high priority |
We also noticed that behaviour and it stops us from migrating from 12.0 to 12.2. Also the pageProps are empty on the second render but not on the first and we use them extensively. |
@Escapado Just curious to know, are you using catch-all routes + dynamic routes together? Because that's the exact same issue that I have and I wonder if besides double rendering, ignoring the props for the second render is because of this directory structure or if it's a common issue with new middleware in 12.2? |
@imangm I am not sure if he has done the same like us, but I can assure you this just starts happening in 12.2 (for me at least). I confirm that 12.1.4 works fine for me. |
We are looking into this on the nextjs team and it will be addressed with high priority. Thank you for all the background and discussion here everyone 🙏 |
Hi, to add some context here, the additional render when an SSG page matches middleware is currently expected as middleware can provide additional query values that the SSG page may be expecting, so along with the query updating process we already do for static pages (related docs) we also trigger this update when middleware matches. We have investigated skipping the render when the router state has not changed (related PR) although there are edge cases that need to be investigated there for this optimization and an additional render should not cause performance issues unless expensive logic is blocking renders which can hurt performance regardless of this additional render. |
@jjjjjjj |
@ijjk Thank you for checking this. However could you please confirm if this behavior was the same with the old _middleware or not? As I checked it wasn't like this and it was only rendering the pages once. Also if you kindly check it after changing Network throttling to Slow 3G to slow down things, you'll notice that the page reloads completely. Please also check the scenario that using dynamic-routes that have a parent catch-all route because it re-renders the second time without passing the props and will render inside the component of the catch-all. To be more clear, it loads the whole "dynamic route" file. Then refreshes the page with "Catch-all route" and doesn't send any props and the page will break. Thanks again |
Hi @ijjk the PR above adds a validation on top of the existing feature to prevent this from happening. What is the root cause for the issue? Is it possible to have the root cause fixed instead? |
Hi all! I'm going to verify if it's safe to re-land #37431 and also add a test for this specific issue.
The reason why it was happening in the first place is we can't easily tell if there's gonna be a query or not, when accessing to certain routes. If there's a query, a re-render to update the route state is necessary to avoid hydration mismatch issues. |
I'm seeing the exact same thing. Vercel should be ashamed of this release. It has broken a lot of functionality and took a long time to figure out. Basically if you have a middleware file, this is a problem. Routes with parent catch alls get randomly rendered on the client side. Shallow routing doesn't work. I even noticed a whole bunch of extra data loading methods for unrelated pages being done in the network tab. For now I will have to revert my app back a version... |
Same here, this behaviour breaking shallow routing sent me back to a previous version of Next. Pretty bad bug. |
Any news from #38422 ? |
Nothing changed with latest version :( |
Lands #37431 again, but it only solves the re-render issue completely for the middleware case (closes #38267), not the `rewrites` case (#37139). For `rewrites`, the blocker is `isReady` always being `false` initially and to match the markup on hydration we can't simply work around it without a re-render. Need to come up with another fix. ## Bug - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Errors have helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm lint` - [ ] The examples guidelines are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing.md#adding-examples)
Thank you |
This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you. |
Verify canary release
Provide environment information
Operating System:
Platform: win32
Arch: x64
Version: Windows 10 Home
Binaries:
Node: 14.18.0
npm: N/A
Yarn: N/A
pnpm: N/A
Relevant packages:
next: 12.2.1-canary.2
eslint-config-next: 12.2.0
react: 18.2.0
react-dom: 18.2.0
What browser are you using? (if relevant)
Chrome 103.0.5060.66
How are you deploying your application? (if relevant)
next start, Vercel
Describe the Bug
By using the new stable middleware.js at the root of the project, all pages will render twice. With the old _middleware.js, there was no similar problem. Please note that if you rename or remove middleware.js from root, it works without any issues.
Expected Behavior
Pages render only once
Link to reproduction
https://github.com/imangm/nextjs-middleware-rerender
To Reproduce
npm run build
npm run start
npm run dev
, you can check the chrome console to see the re-renderThe text was updated successfully, but these errors were encountered: