2

We're using the middleware and we just found out it executes things twice, even the application itself. I know that middleware is being used in resources as well, so I put a matcher and removed the "favicon" because I heard it can cause this bug.

When we use the middleware, and console.log in "_app.tsx", we see that it renders twice. Also I put a counter in middleware.ts and every page I enter I see that it increases the counter by two.

My middleware.ts page looks like:

import { NextRequest, NextResponse } from "next/server";

let counter = 0;
export function middleware(request: NextRequest) {
  const response = NextResponse.next();
  counter++;

  console.log("middleware #", counter);
  return response;
}

Github repo to reproduce: https://github.com/ornakash/reproduction-template-nextjs

I only see it twice in the server's terminal (in browser I see only one console.log). Do you have any idea why it happens?

Or Nakash
  • 1,345
  • 1
  • 9
  • 22

1 Answers1

1

You are using strict mode in React in your next.config.js file. From the documentation:

By intentionally double-invoking methods like the component constructor, strict mode makes patterns like this easier to spot.

Strict mode runs a lot of methods twice like constructor, componentWillMount, componentWillReceiveProps, componentWillUpdate, getDerivedStateFromProps, shouldComponentUpdate, render, setState, and updater functions.

I was also confused and asked a question. You should still be able to use strict mode - the extra render is fine. If you are trying to investigate why an extra render occurs (and console.log repeats), then you will be confused until you realize it because of strict mode. However, If strict mode is producing unexpected behaviors in the operation of your application (minus the extra render), you likely have a bug.

In production strict mode does not run code twice.


Edit: If you are sure this is not the issue... you should run a check to see if the double renders are from running first on the server SSR then on the client.

if (typeof window === 'undefined') {
    console.log('running on server');
} else {
    console.log('running on client');
}

Also I put a counter in middleware.ts and every page I enter I see that it increases the counter by two.

The above statement could be caused by strict mode, whereas the _app.tsx issue could be the SSR / client.

Diesel
  • 5,099
  • 7
  • 43
  • 81
  • 1
    Thanks for your appreciated comment! I disabled reactStrictMode (it's called this in next.js), so unfortunately that's not the issue. Also it happens only in server terminal (not in browser) – Or Nakash Aug 24 '22 at 19:04
  • @OrNakash Hopefully you are sure that it is not strict mode (`reactstrictmode` is just strict mode as a setting in nextJS where they put that in for you). If you are sure, I edited my post for another possible situation that can help you start figuring out why a double render is occurring. – Diesel Aug 24 '22 at 19:36
  • Thank you so much for all the help. I just console.logged what you wrote above, and all I see that it is re-rendering the server twice! even when I put that on client (_app.tsx) so probably the problem is with the server. So it means something. I think they have something with the middleware – Or Nakash Aug 24 '22 at 22:47
  • @OrNakash - you can wait to load it on the client avoiding those re-renders. But that may hurt the client. I'd first ask if you are having an issue because of the extra renders. If not, it may be fine (and even intentional from the middleware). Premature optimization may create issues and not be worth the time. But if it is an issue - you will forget about it in a few years. So I'd write up a note about what you found and move on if everything is working fine. – Diesel Aug 25 '22 at 18:25