Getting NEXT_REDIRECT error, when trying to redirect Server Actions in Next.js 13.
Answered
Satin Angora posted this in #help-forum
Satin AngoraOP
Hi, we are currently implementing authentication for our client, and have a blocking issue which for some reason exists in Next.js 13. In some cases the
Suppose the route of this layout is
Now, whenever I try to redirect from Server Actions from route
redirect()
function from next/redirect
works properly. For example, one instance where it works properly is a nested layout.tsx
file. Here are the contents:export default async function Layout({ children }: LayoutProps) {
if (!cookies().get("jwt")) redirect("/b");
return (
<></>
);
}
Suppose the route of this layout is
/a
.Now, whenever I try to redirect from Server Actions from route
/c
to /a/b
, it throws the error attached to this thread as an image. It also failes to redirect to /a
or /
directly for some reason.Answered by fuma ๐ joulev
You have to use client-side redirect instead:
import { useRouter } from "next/navigation";
const router = useRouter();
router.push("/b");
8 Replies
Satin AngoraOP
Here's the code where it's implemented:
"use client";
import Image from "next/image";
import { useEffect, useRef } from "react";
import GenericButton from "../../components/GenericButton";
import axios from "axios";
import { onboard } from "./_actions";
import favicon from "../favicon.ico";
export default function Page() {
const googleOAuthButtonRef = useRef<HTMLButtonElement | null>(null);
useEffect(() => {
window.google.accounts.id.initialize({
itp_support: true,
callback: async ({ credential }) => {
const response = await axios.post("/api/v1/onboard", {
strategy: "google",
credential,
});
console.log({ credential, response });
if (response.status === 200) await onboard(response.data.token);
},
client_id: process.env.NEXT_PUBLIC_GOOGLE_OAUTH_CLIENT_ID!,
});
window.google.accounts.id.disableAutoSelect();
window.google.accounts.id.renderButton(googleOAuthButtonRef.current!, {
type: "standard",
size: "medium",
text: "continue_with",
theme: "outline",
shape: "pill",
locale: "en-US",
logo_alignment: "left",
});
window.google.accounts.id.prompt();
}, []);
return (
<div className="w-full h-screen flex items-center justify-center">
<div className="w-full flex gap-8">
<div className="flex items-center flex-col gap-2">
<GenericButton className="w-full">
Continue with Email
</GenericButton>
<button ref={googleOAuthButtonRef}></button>
</div>
</div>
</div>
);
}
And here's the code for the server action:
"use server";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { add, getMilliseconds } from "date-fns";
export async function onboard(token: string) {
cookies().set({
path: "/",
name: "jwt",
value: token,
// The internal state cookie will expire in 1.5 months, and the user will need to
// login again to access the platform.
expires: getMilliseconds(add(new Date(), { months: 1, days: 15 })),
});
redirect("/dashboard/control");
}
You have to use client-side redirect instead:
import { useRouter } from "next/navigation";
const router = useRouter();
router.push("/b");
Answer
As I remember,
redirect
in server actions only works when you're firing it from formsSatin AngoraOP
Oh, interesting. Thank you. Cookies should work fine right?
yes,
cookies
always work in server actionsSatin AngoraOP
Ok, thank you.
Tufted Flycatcher
thank you @fuma ๐ joulev