Next.js Discord

Discord Forum

Redirect is not working in server. Error: NEXT_REDIRECT (v14)

Unanswered
Giant Angora posted this in #help-forum
Open in Discord
Avatar
Giant AngoraOP
import { auth } from "@/firebase";
import { signInWithEmailAndPassword } from "firebase/auth";
import { NextApiResponse } from "next";
import { redirect } from "next/navigation";
import { NextRequest, NextResponse } from "next/server";

export async function POST(req: NextRequest, res: NextApiResponse) {
try {
const data = await req.json();
const { email, password } = data;
// // Start: Firebase action
// const userCredentials = await signInWithEmailAndPassword(
// auth,
// email,
// password
// );
// const user = userCredentials.user;
// console.log(user)
// End: Firebase action
redirect('/feed')

} catch (error: any) {
return NextResponse.json(
{
error: error.message,
},
{
status: 500,
}
);
}
}

51 Replies

Avatar
redirect works by throwing special error, so you either have to rethrow it or not have it in try catch
Avatar
Giant AngoraOP
can you code that plz
@risky
Avatar
import { auth } from "@/firebase";
import { signInWithEmailAndPassword } from "firebase/auth";
import { NextApiResponse } from "next";
import { redirect } from "next/navigation";
import { NextRequest, NextResponse } from "next/server";

export async function POST(req: NextRequest, res: NextApiResponse) {
  try {
    const data = await req.json();
    const { email, password } = data;
    // // Start: Firebase action
    // const userCredentials = await signInWithEmailAndPassword(
    //   auth,
    //   email,
    //   password
    // );
    // const user = userCredentials.user;
    // console.log(user)
    // End: Firebase action
    redirect("/feed");
  } catch (error) {
    if (error instanceof Error) {
      if (error.message === "NEXT_REDIRECT") throw error;

      return NextResponse.json(
        {
          error: error.message,
        },
        {
          status: 500,
        }
      );
    } else if (typeof error === "string") {
      return NextResponse.json(
        {
          error,
        },
        {
          status: 500,
        }
      );
    }
  }
}
Avatar
Giant AngoraOP
@Ray it should redirect to "/feed". Rather it is successfully logging in but not redirecting
Image
Avatar
oh didn't notice thats a route handler
import { auth } from "@/firebase";
import { signInWithEmailAndPassword } from "firebase/auth";
import { NextApiResponse } from "next";
import { redirect } from "next/navigation";
import { NextRequest, NextResponse } from "next/server";

export async function POST(req: NextRequest, res: NextApiResponse) {
  try {
    const data = await req.json();
    const { email, password } = data;
    // // Start: Firebase action
    // const userCredentials = await signInWithEmailAndPassword(
    //   auth,
    //   email,
    //   password
    // );
    // const user = userCredentials.user;
    // console.log(user)
    // End: Firebase action
    return NextResponse.redirect("/feed", {status: 302});
  } catch (error) {
    if (error instanceof Error) {
      return NextResponse.json(
        {
          error: error.message,
        },
        {
          status: 500,
        }
      );
    } else if (typeof error === "string") {
      return NextResponse.json(
        {
          error,
        },
        {
          status: 500,
        }
      );
    }
  }
}
Avatar
Giant AngoraOP
@Ray
Image
Avatar
return NextResponse.redirect(new URL("/feed", req.nextUrl), {status: 302});
Avatar
Giant AngoraOP
@Ray Still the same, you can see the netwrok tab, redirect to feed..... But in browser it is not redirecting
Image
Avatar
use 302 instead of 303
Avatar
Giant AngoraOP
same!
🥲
@Ray
Avatar
you should handle it on client side
const res = await axios.post()
if (res.redirected) {
   router.push("/feed")
}
Avatar
Giant AngoraOP
but why it is doing this, as It is working fine
any idea?
Avatar
fetch returns the data to be handled by JavaScript without causing the browser to navigate at all (although you don't do anything with the return value of fetch).
Avatar
Giant AngoraOP
But I made a request in postman on the same API, it returns the /feed response as HTML
it is getting response
Avatar
because postman not submitting with fetch
so what is your issue?
Avatar
Giant AngoraOP
it is getting /feed as response and logging in successfully, but not redirecting
Avatar
because the endpoint return redirect to the response, so postman get the html
Avatar
Giant AngoraOP
You can see in the browser network tab as send earlier
Avatar
have you do this?
Avatar
Giant AngoraOP
I was doing the same before, it was redirect. But this is using client side. I have to redirect using server side
Basically, I refactored the code from client to server
Avatar
so how does your code look like now?
how do you submit the form?
Avatar
Giant AngoraOP
const onSubmit: SubmitHandler<{ email: string; password: string; }> = async ({ email, password }) => { try { // show loader showLoader(); // hit api request for login await axios.post("/api/auth/login", { email: email, password: password, }); // show success message toast({ variant: "default", description: "Logged in successfully!" }); } catch (error: any) { // show error message toast({ variant: "destructive", title: "Uh oh! Something went wrong.", description: error.message, }); } finally { // hide loader hideLoader(); } };
Avatar
you are submitting with axios(fetch)
so you need to do this
Avatar
Giant AngoraOP
so if I use fetch() what do I need to do?
this is client side redirection
Avatar
use server action instead of axios/fetch then
Avatar
Giant AngoraOP
Please can you give me the starter code for that
Avatar
Giant AngoraOP
Image
Avatar
no, you can't just add 'use server'
btw, I don't think it would work with
import { signInWithEmailAndPassword } from "firebase/auth";
I think you got error with route handler too right?
so you have to comment it out
Avatar
Giant AngoraOP
No, it is doing the same,
logging in but not redirecting
Avatar
oh ok
use server action then
Avatar
Giant AngoraOP
I think it will take time to resolve until then I will use router.push
Anyways, thanks for helping. 🫂
Avatar
yeah, what you need to do is
1. convert the route handler to server action
2. change onSubmit to action props on the form element