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");
}
fuma ๐ joulev
You have to use client-side redirect instead:
import { useRouter } from "next/navigation";
const router = useRouter();
router.push("/b");
Answer
fuma ๐ joulev
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?
fuma ๐ joulev
yes,
cookies
always work in server actionsSatin AngoraOP
Ok, thank you.
Tufted Flycatcher
thank you @fuma ๐ joulev