next.js: Fast refresh not working properly due to page reload when compiling middleware

What version of Next.js are you using?

12.0.4

What version of Node.js are you using?

16.13.0

What browser are you using?

Chrome, Safari, Edge

What operating system are you using?

macOS

How are you deploying your application?

next dev

Describe the Bug

Since I don’t know the technological background or necessity of the page reload for middleware, I’m not sure if that’s something that you have to live with when working with middleware - but any change, like edits made to react components, often trigger a page reload due to the middleware being compiled:

wait - compiling /_middleware (middleware only)…

This becomes especially frustrating when working with getStaticProps.

Expected Behavior

No page reload when applying changes (“Fast Refresh”).

To Reproduce

Basic middleware implementation.

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 26
  • Comments: 50 (14 by maintainers)

Commits related to this issue

Most upvoted comments

Hey! I was facing the same issue until I found the problem: something that is imported in the middleware and somewhere in the app. The import could be anything, including an external dependency. Here is the minimal reproduction: henriqemalheiros/middleware-fast-refresh.

To reproduce it, though, you need to wait ~20 seconds after the page is fully loaded or the last change was made. If you make a change before the ~20 seconds interval, the fast refresh works as expected. After that, any change to any part of the app triggers a full refresh.

There is a warning logged to the console, but it’s to fast to actually read it. In next@canary, the same warning is shown by the app before the full refresh so we can read it:

About to perform a full refresh

Fast Refresh will perform a full reload when you edit a file that is imported by modules outside of the React rendering tree. It is also possible the parent component of the component you edited is a class component, which disables Fast Refresh. Fast Refresh requires at least one parent function component in your React tree.

You can find more information in the related Webpack error below:

Cannot read properties of undefined (reading 'call')

You can read more about Fast Refresh in our documentation.

Hi friends! Just want to say that we are aware of this issue on the next.js core team and are working towards getting a fix out. Really appreciate your patience here, and so sorry to everyone who this has inconvenienced!

Hi, this has been updated in v12.0.11-canary.1 of Next.js, please update and give it a try!

This is pretty frustrating and severely hindering the development experience. Every time I update code it does a full refresh to a blank page and I have to refresh twice to get it to render.

I have imports in my _middleware – there’s not really much I can do to get around that. Can I disable re-compilation on a particular nextjs path? That file isn’t changing at all, it should be compiled once until any changes are made.

I was able to reproduce this, Developer Experience when using middleware is bad, the fast refresh won’t work properly (editing a simple changes will get a full reload), hope this can get further investigation

@jescalan & @ijjk since serving the public is an often thankless task, I just want to say thank you so much for this, it has really been a thorn in the side and this is probably the highlight to the day.

Just wanted to share that, pass it along to anyone involved, pats on the back for all.

Hi, this has been fixed on latest (as of writing 12.0.9) please upgrade and give it a try!

Also seeing frequent reloads with 12.0.7 when working due to the middleware recompiling.

With canary it is perhaps a little less frequent, but instead of just a reload I first get this dialog - to be honest, it was better before, as I didn’t have to click a button to reload also.

image

This is just doing/undoing the same change to a styled component over and over which works like 3 in 4 times, and does a full reload 1 in 4. I see wait - compiling /_middleware... in the console despite not changing the middleware.

My middleware is just the basic auth example and is totally self contained, except for importing TS types: import { NextRequest, NextResponse } from "next/server"; so it’s not related to the shared imports some others have mentioned.

I can confirm that removing middleware.ts fixes this, but doing an early return from the middleware in dev mode does not help.

My project is too large and complex to share as a repro, but if no one else has created one I can try and create one.

No, I am not importing NextRequest or NextResponse from elsewhere, so for me this is not caused by imports in middleware that are also imported elsewhere. I get a slightly different error on 12.0.8 vs canary:

image

For now I’ve resorted to renaming the middleware file while I have styling work to do, then renaming it back

FWIW I’ve been having this issue as well very frequently with 12.0.8; virtually every change triggers a full request of the page, renaming the middleware didn’t help (I only have one global middleware and it does not have any external imports).

I thought https://github.com/vercel/next.js/pull/31548 would fix this issue, but I am experiencing the same at the latest v.12.0.7

FWIW I’ve been having this issue as well very frequently with 12.0.8; virtually every change triggers a full request of the page, renaming the middleware didn’t help (I only have one global middleware and it does not have any external imports).

for us the workflow is deleting all the middlewares before starting on features. and to avoid committing the deleted files, weve created a pre-commit check that fails if they get removed 😎

@henriqemalheiros nice work! this has been really hurting my productivity, thanks for coming up with a reproduction.

To reproduce, add some JSX and save your project, repeat 4 - 5 times and you should get a reload.

@ijjk I can confirm that I don’t see the complete refresh in the two projects I tested with that version !

After upgrading to canary I see the dialog as well, but with a different error message. I didn’t see anything related to on-demand-entries before upgrading to canary. Hoping this is helpful:

image

@balazsorban44, which version resolves this issue? next@latest is v12.0.7, and it wasn’t fixed there.

Can also confirm this is fixed. Thank you so so so much!!

Hello @balazsorban44, I just created a quick reproduction repository : https://github.com/bmichotte/next-issue-31827

With that project cloned, you have to

  1. yarn install
  2. yarn dev
  3. open http://localhost:3000/ (and enjoy an Hello world 😛)
  4. wait a few seconds, then uncomment the console.log in the api/v1/hello.ts file
  5. save that file
  6. reproduce 4-5 with commenting/uncommenting the console.log, you should see the full reload

Still seeing this issue on 12.0.9

image

@WoutGroenendijk you must still have import { NextRequest, NextResponse } from "next/server"; though, right? For me this happens just with that as the only import

I ran into the same issue after upgrading to next 12.0.8, this was caused by my custom imports in the _middleware. After removing the imports and moving them inside the _middleware file it all worked fine.

@GandharvJaggi if you are not using middleware then this sounds unrelated to your issue, can you open a separate issue with a reproduction to allow investigation?

Yup, definitely not fixed on 12.0.9. Here’s the stacktrace that I’m getting:

TypeError: Cannot read properties of undefined (reading 'call')
    at Object.options.factory (http://localhost:3000/_next/static/chunks/webpack.js?ts=1643268216530:685:31)
    at __webpack_require__ (http://localhost:3000/_next/static/chunks/webpack.js?ts=1643268216530:37:33)
    at fn (http://localhost:3000/_next/static/chunks/webpack.js?ts=1643268216530:354:21)
    at eval (webpack-internal:///./app.config.ts:30:68)

As soon as I remove any module imports - the problem is gone.