App when redirecting protected routes with the new NextJS 12.2 middleware

Viewed 453

I'm updating my next to 12.2.0.

I used to have my middleware nested in Pages/_middleware but with this newer version this doesn't work anymore.

I'm following the upgrade guide

Gone from this:

src/Pages/_middleware.js

export function middleware(req) {
  const userSession = req.headers.get('cookie');
  const url = req.nextUrl.clone();

  if (userSession?.includes('userToken')) {
    if (req.nextUrl.pathname === '/login') {
      url.pathname = '/';

      return NextResponse.redirect(url);
    }
    return NextResponse.next();
  }

  url.pathname = '/login';
  return NextResponse.rewrite(url);
}

To this

src/middleware.js

    import { NextResponse } from 'next/server';

 export function middleware(req) {
  const userSession = req.headers.get('cookie');
  const reqUrl = req.nextUrl.pathname;

  if (userSession?.includes('userToken')) {
    if (reqUrl.startsWith('/login')) {
      // this one works!
      return NextResponse.redirect(new URL('/', req.url));
    }
    return NextResponse.next();
  }

  if (reqUrl.startsWith('/login')) {
    return NextResponse.next();
  };

  const loginUrl = new URL('/login', req.url);

  return NextResponse.redirect(loginUrl);
};

However once the user is redirected to /login he gets a blank page (no next html) and all these errors in the console:

Uncaught SyntaxError: Unexpected token '<' (at react-refresh.js?ts=1656708611639:1:1) webpack.js?ts=1656708611639:1 Uncaught SyntaxError: Unexpected token '<' (at webpack.js?ts=1656708611639:1:1) main.js?ts=1656708611639:1 Uncaught SyntaxError: Unexpected token '<' (at main.js?ts=1656708611639:1:1) _app.js?ts=1656708611639:1 Uncaught SyntaxError: Unexpected token '<' (at _app.js?ts=1656708611639:1:1) courses.js?ts=1656708611639:1 Uncaught SyntaxError: Unexpected token '<' (at courses.js?ts=1656708611639:1:1) _buildManifest.js?ts=1656708611639:1 Uncaught SyntaxError: Unexpected token '<' (at _buildManifest.js?ts=1656708611639:1:1) _ssgManifest.js?ts=1656708611639:1 Uncaught SyntaxError: Unexpected token '<' (at _ssgManifest.js?ts=1656708611639:1:1)

Oddly, the first if statement redirect when the user is auth works.

Edit 2

If I add a matcher as per in the docs, it works:

// middleware.js

export function middleware(req) {
...
}

export const config = {
  matcher: ['/login', '/'],
};

However, I can't add a match for every protected route. It's a complete overkill.

1 Answers

Was this working before? By reading the logic, it seems like an endless loop to me:

  • if the user lands in /login, they get redirected to /
  • if the user lands in somewhere else, they get redirected to /login

I know there are some extra conditions to match those redirects, but I think in your case you are matching them, ending in an endless loop of redirects:

  1. You have the userToken and try to access /login --> by your logic, it gets redirected to /
  2. You have the userToken and try to access / (or whatever other URL really) --> by your logic, it gets redirected to /login
  3. You have the userToken and try to access /login --> This is point 1 again!
Related