rsnext/errors/nested-middleware.md
Javi Velasco f354f46b3f
Deprecate nested Middleware in favor of root middleware (#36772)
This PR deprecates declaring a middleware under `pages` in favour of the project root naming it after `middleware` instead of `_middleware`. This is in the context of having a simpler execution model for middleware and also ships some refactor work. There is a ton of a code to be simplified after this deprecation but I think it is best to do it progressively.

With this PR, when in development, we will **fail** whenever we find a nested middleware but we do **not** include it in the compiler so if the project is using it, it will no longer work. For production we will **fail** too so it will not be possible to build and deploy a deprecated middleware. The error points to a page that should also be reviewed as part of **documentation**.

Aside from the deprecation, this migrates all middleware tests to work with a single middleware. It also splits tests into multiple folders to make them easier to isolate and work with. Finally it ships some small code refactor and simplifications.
2022-05-19 15:46:21 +00:00

1.3 KiB

Nested Middleware

Why This Error Occurred

You are defining a middleware file in a location different from <root>/middleware which is not allowed.

While in beta, a middleware file under specific pages implied that it would only be executed when pages below its declaration were matched. This execution model allowed the nesting of multiple middleware, which is hard to reason about and led to consequences such as dragging effects between different middleware executions.

The API has been removed in favor of a simpler model with a single root middleware.

Possible Ways to Fix It

To fix this error, declare your middleware in the root folder and use NextRequest parsed URL to define which path the middleware code should be executed for. For example, a middleware declared under pages/about/_middleware.js can be moved to middleware. A conditional can be used to ensure the middleware executes only when it matches the about/* path:

import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  if (request.nextUrl.pathname.startsWith('/about')) {
    // Execute pages/about/_middleware.js
  }
}

If you have more than one middleware, you will need to combine them into a single file and model their execution depending on the request.