next.js icon indicating copy to clipboard operation
next.js copied to clipboard

Server Actions don't respect the `NextResponse.redirect` from Middleware

Open Yihao-G opened this issue 1 year ago • 1 comments

Link to the code that reproduces this issue

https://codesandbox.io/p/devbox/server-action-and-middleware-redirect-j54l2f

To Reproduce

See the reproduction link.

TL;DR:

  1. Have a server action that gets called from a client component's button
  2. Add a middleware that returns NextResponse.redirect() when request.method === 'POST' (P.S. the condition could be authenticating the user session)
  3. Click the button to trigger the server action
  4. The page doesn't redirect as instructed in the middleware

Current vs. Expected behavior

Current: The page doesn't redirect Expected: The page redirects as instructed in the middleware

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #1 SMP PREEMPT_DYNAMIC Sun Aug  6 20:05:33 UTC 2023
  Available memory (MB): 4102
  Available CPU cores: 2
Binaries:
  Node: 20.11.1
  npm: 10.2.4
  Yarn: 1.22.19
  pnpm: 8.15.4
Relevant Packages:
  next: 14.3.0-canary.40 // Latest available version is detected (14.3.0-canary.40).
  eslint-config-next: 14.2.1
  react: 18.2.0
  react-dom: 18.2.0
  typescript: 5.4.5
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Middleware

Which stage(s) are affected? (Select all that apply)

next dev (local)

Additional context

The reason is that the server action's fetch call follows the redirect: https://github.com/vercel/next.js/blob/1ae14bafdb197a712c0bbb9b6570f4d04bd849e3/packages/next/src/client/components/router-reducer/reducers/server-action-reducer.ts#L62-L80

There is also no consistent way to handle it (catching the server action errors) on the client side. If the redirected page responds 2xx, the server action doesn't throw an error.

A workaround would be mimicking the server actions' redirect() response in the middleware:

  if (request.headers.get('Accept') === 'text/x-component') {
    return new NextResponse(null, {
      status: 303,
      headers: {
        'X-Action-Redirect': url
      }
    });
  }

However, this workaround feels very hacky.

Related issue: #62469

Yihao-G avatar May 06 '24 03:05 Yihao-G

any news ? @Yihao-G i have the same issue,...middleware doesnt trigger redirection when called from client not from routing

minlost avatar Jul 02 '24 20:07 minlost

This is still an issue in Next.js 15. For now I created a function using your workaround, but it would be nice if the middleware redirect response took care of it automatically.

jeremy-step avatar Nov 11 '24 13:11 jeremy-step

Looks like this issue is being ignored! , Thanks @Yihao-G

residentcode avatar Jan 13 '25 18:01 residentcode

@vercel-release-bot @leerob

Any update on this? When the middleware is reached cuz of a server action (method === POST), the NextResponse.redirect is not working.

t-monaco avatar Apr 04 '25 08:04 t-monaco