#server actions inside client components, redirect is happening even when throw error?

1 messages · Page 1 of 1 (latest)

slender mountainBOT
#

Hi @sterile canopy. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

Based on the knowledge sources provided, it appears that there is indeed an issue with redirects in server actions when used inside client components, even when errors are thrown. This behavior is related to recent changes in Next.js. Let me explain:

  1. The redirect function internally throws a NEXT_REDIRECT error, which is used by Next.js to handle the redirection process Github Issue #71740 (https://github.com/vercel/next.js/issues/71740).

  2. As of Next.js version 15.0.0-canary.160, this NEXT_REDIRECT error now leaks to the client code, whereas previously it did not Github Issue #71831 (https://github.com/vercel/next.js/issues/71831).

  3. Even when the NEXT_REDIRECT error is caught in a try/catch block on the client side, the redirect will still have been handled by Next.js Github Issue #71831 (https://github.com/vercel/next.js/issues/71831).

  4. To handle this situation, it's recommended to use the unstable_rethrow() function. However, this can lead to additional network requests, as explained in the issue Github Issue #71831 (https://github.com/vercel/next.js/issues/71831).

Here's an example of how you might handle this in a client component:

<form
  onSubmit={async (e) => {
    try {
      e.preventDefault();
      await action();
    } catch (error) {
      unstable_rethrow(error);
    }
  }}
>
  <button>Click me</button>
</form>

It's worth noting that this behavior is considered intended by the Next.js team, as mentioned in Github Issue #71740 (https://github.com/vercel/next.js/issues/71740). However, it does seem to cause some confusion and potential issues for developers.

#

If you're experiencing problems with this behavior, you might want to consider alternative approaches, such as handling redirects on the client side using router.push() from the useRouter hook, as suggested in Github Issue #59163 (https://github.com/vercel/next.js/issues/59163).

Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: