rsnext/errors/returning-response-body-in-middleware.md
Lee Robinson 5d4ac47f7a
Improve response body in Middleware error page. (#38537)
* Improve respond body in Middleware error page.

* Apply suggestions from code review

Co-authored-by: JJ Kasper <jj@jjsweb.site>
2022-07-18 20:20:23 -05:00

2 KiB

Returning response body in Middleware

Why This Error Occurred

Middleware can no longer produce a response body as of v12.2+.

Possible Ways to Fix It

Migrate to using rewrite/redirect to Pages/API Routes handling a response.

Explanation

To respect the differences in client-side and server-side navigation, and to help ensure that developers do not build insecure Middleware, Middleware can no longer produce a response body. This ensures that Middleware is only used to rewrite, redirect, or modify the incoming request (e.g. setting cookies).

The following patterns will no longer work:

new Response('a text value')
new Response(streamOrBuffer)
new Response(JSON.stringify(obj), { headers: 'application/json' })
NextResponse.json()

How to upgrade

For cases where Middleware is used to respond (such as authorization), you should migrate to use rewrite/redirect to pages that show an authorization error, login forms, or to an API Route.

Before

// pages/_middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { isAuthValid } from './lib/auth'

export function middleware(request: NextRequest) {
  // Example function to validate auth
  if (isAuthValid(request)) {
    return NextResponse.next()
  }

  return NextResponse.json({ message: 'Auth required' }, { status: 401 })
}

After

// middleware.ts
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
import { isAuthValid } from './lib/auth'

export function middleware(request: NextRequest) {
  // Example function to validate auth
  if (isAuthValid(request)) {
    return NextResponse.next()
  }

  request.nextUrl.searchParams.set('from', request.nextUrl.pathname)
  request.nextUrl.pathname = '/login'

  return NextResponse.redirect(request.nextUrl)
}