Next.js Discord

Discord Forum

Server Action causes a re-render

Unanswered
Ichneumonid wasp posted this in #help-forum
Open in Discord
Ichneumonid waspOP
Hello, I have a server action that is used in a client component for deleting the current user from my system. The client component is part of the /profile page which is server side. Whenever the client component calls the server action, when the server action returns I have a redirect to a /goodbye page. However, the server action causes a page re-render on return, and since my /profile is protected, the user has been deleted and I get an error that the user is not authenticated and redirects back to /login.

I know that if instead of a server action I implement this as an internal API and then fetch I wont get that re-render but to me it feels weird having everything as a server action and just 1 thing as an API route (I know that even server actions are made into POST routes in the end but at least organization/project wise).

Is there a way to fix/handle this or do I just make it into an API route? Or do I turn all my server actions into API routes?

8 Replies

@Ichneumonid wasp Hello, I have a server action that is used in a client component for deleting the current user from my system. The client component is part of the /profile page which is server side. Whenever the client component calls the server action, when the server action returns I have a redirect to a /goodbye page. However, the server action causes a page re-render on return, and since my /profile is protected, the user has been deleted and I get an error that the user is not authenticated and redirects back to /login. I know that if instead of a server action I implement this as an internal API and then fetch I wont get that re-render but to me it feels weird having everything as a server action and just 1 thing as an API route (I know that even server actions are made into POST routes in the end but at least organization/project wise). Is there a way to fix/handle this or do I just make it into an API route? Or do I turn all my server actions into API routes?
Saltwater Crocodile
The issue isn't authentication itself, it's that Server Actions trigger a re-render of the current route when they finish. Since /profile is protected and the user is already deleted, the auth guard runs again and redirects to /login before the /goodbye redirect can take effect.
The clean fix is to call redirect("/goodbye") directly inside the Server Action so execution stops and the page never re-renders. Alternatively, this specific action can live in a route handler since it changes auth state, there's no need to convert all Server Actions.
"use server";
import { redirect } from "next/navigation";

export async function deleteAccount() {
await deleteUser();
await signOutUser(); // if needed
redirect("/goodbye");
}
Ichneumonid waspOP
But if the server action is wrapped in a try catch the redirect throws an exception
Ichneumonid waspOP
Actually also if I signout in the server action i get again redirected to the login page
Saint Hubert Jura Hound
I would just move the redirect outside of the try catch
@Ichneumonid wasp But if the server action is wrapped in a try catch the redirect throws an exception
Cinnamon Teal
You can't have redirect() inside try-catch blocks as redirect internally throws an error. So if you catch that error it won't work properly. https://nextjs.org/docs/app/api-reference/functions/redirect#behavior

when the server action returns I have a redirect to a /goodbye page.
It's not very clear to me where you are calling the redirect from, but if you call the redirect(/goodbye) inside your server action, right after you call your signout function, it should work.

This is assuming your /goodbye route is somehow not behind an auth and is accessible.
Cinnamon Teal
Hmm… Not really sure what’s going on TBH.

But why do you want a try catch on the client wrapping a server action? How are you actually calling your server action?

Since server actions are POST requests I almost always call them via form actions, or onSubmit of a form if I am using something like React Hook Form on the client, so I don’t think I have ever wrapped a one in a try catch.

I will have try catches inside the server action on things that could fail, but yeah.

Ether way I can’t really picture what may be going wrong.