Server Action causes a re-render
Unanswered
Ichneumonid wasp posted this in #help-forum
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?
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.
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");
}
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
This is assuming your
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#behaviorwhen 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 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.
Ichneumonid waspOP
i mean the client component wraps the server action in a try catch, I dont have any try catches in my server action. Also whenever I sign out the user in the server action before I redirect I also get auth errors in my profile page
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
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.
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.