skip to Main Content

I have a button that submits a form. That submit function runs a post request to my api route and in the api route, I insert a row in my database. I need to redirect the user to / when its all done. But for some reason return redirect("/") just doesn’t work. My tab just stays on loading and nothing happens.

Submit function:

const handleSubmit = async () => {;
        try {
            const res = await fetch("/api/saveRecipe", {
                method: "POST", 
                headers: {
                    "Content-Type": "application/json",
                },
                body: JSON.stringify({
                    title: title,
                    time: time,
                    time_unit: timeUnit,
                    serves: serves,
                    ingredients: ingredients,
                    instructions: instructions,
                }),
            });
      
        } catch (e) {
            console.log(e.message || e.description);
        }
    };

api/saveRecipe/route.js

import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
import { cookies } from "next/headers";
import { redirect } from "next/navigation";
import { NextResponse } from "next/server";

export const dynamic = "force-dynamic";
export async function POST(req) {
    const supabase = createRouteHandlerClient({ cookies });
    try {
        const data = await req.json();
        const { recipe, error } = await supabase.from("Recipes").insert([data]);
        if (error) {
            throw error;
        }
    } catch (error) {
        console.log(error.description || error.message);
    }

    return redirect("/");
}

The row gets added to the database successfully so its not a problem with the api calls. And this exact redirect line was used in another route and it works fine so idk what’s going on

2

Answers


  1. You are trying to use redirect() inside of API Route, this does not work because this function can only be used inside a server-component. You can redirect the user like this after adding the "use-client"directive at the top of your component:

    "use client";
    
    import { useCallback } from "react";
    import { useRouter } from "next/navigation";
    // or from "next/router" if using pages directory
    
    export default function MyComponent() {
      const router = useRouter();
    
      const handleSubmit = useCallback(async () => {
        try {
          const response = await fetch(/* ... */);
          // or route.replace("/") if you don't want to allow back navigation
          router.push("/");
        } catch {
          // handle error
        }
      }, [router]);
    
      return <Button onClick={handleSubmit}>Submit</Button>;
    }
    

    Now simply return a status code from the API indicating success or failure and use something like response.ok to redirect the user based on the form validation status.

    Login or Signup to reply.
  2. you are trying to use next/navigation to redirect the user, but this is not the correct way to do it. You should use next/router to redirect the user. Here is how I did it:

    import { createRouteHandlerClient } from "@supabase/auth-helpers-nextjs";
    import { cookies } from "next/headers";
    import { useRouter } from "next/router";
    
    export const dynamic = "force-dynamic";
    export async function POST(req) {
        const supabase = createRouteHandlerClient({ cookies });
        try {
            const data = await req.json();
            const { recipe, error } = await supabase.from("Recipes").insert([data]);
            if (error) {
                throw error;
            }
        } catch (error) {
            console.log(error.description || error.message);
        }
    
        const router = useRouter();
        router.push("/");
    
        return new Response(null, { status: 302 });
    }
    

    Here, I’m using useRouter to get the router object, and then calling router.push("/") to redirect the user to the home page. Them I’m returning a Response object with a 302 status code to indicate that the response is a redirect.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search