Reputation: 41
I'm currently working on a Next.js 13.4.9 project and I'm facing an issue with redirecting logged in users within a client component using the useEffect
hook. I have tried a certain method, but it keeps throwing an error in the browser (NEXT_REDIRECT
).
import { redirect } from 'next/navigation';
useEffect(() => {
getRedirectResult(auth).then( async (userCredential) => {
if (!userCredential) return;
fetch('/api/auth/login', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + (await userCredential.user.getIdToken()),
},
}).then((res) => {
if (res.ok) {
try {
redirect('/user')
} catch (error) {
console.log(error)
}
}
})
})
}, [])
I would really appreciate it if someone could guide me through the correct approach to redirect logged in users in Next.js using the useEffect
hook. Is there an alternative method I should consider? I don't really want to use a router. Thank you in advance for your help!
Error:
Error: NEXT_REDIRECT at getRedirectError (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/redirect.js:40:19) at redirect (webpack-internal:///(app-client)/./node_modules/next/dist/client/components/redirect.js:50:11) at eval (webpack-internal:///(app-client)/./src/app/(auth)/signin/page.tsx:34:82)
Upvotes: 4
Views: 6611
Reputation: 138
if you want use redirect you can't use redirect in try, you must use redirect in catch or after try catch. this is because redirect() work is by throwing an error that Next.js can handle in order to stop execution of the code.
Here is a the link relevant, for this case : https://github.com/vercel/next.js/issues/49298#issuecomment-1542055642
Upvotes: 2
Reputation: 2853
As far as I know, the redirect
method is meant to be used on the server only. You should use the useRouter
hook when you are running code on the client side. Here is an example:
"use client";
// or `next/router` when using pages directory
import { useRouter } from "next/navigation";
import { useEffect, useCallback } from "react";
export default function ClientComponent(props) {
const router = useRouter();
// wrapped in `useCallback` to avoid re-creating the function on each render
const redirect = useCallback(async () => {
try {
const userCredential = await getRedirectResult(auth);
const token = await userCredential.user.getIdToken();
const response = await fetch("/api/auth/login", {
method: "POST",
headers: { Authorization: `Bearer ${token}` },
});
// you could call also call `router.replace`
if (response.ok) return router.push("/user");
// handle any response errors here
} catch (error) {
// handle any network errors here
}
}, [router]);
useEffect(() => {
// you could also define the function here without `useCallback`,
// this is only done when the function only needs to be called
// inside the effect.
redirect();
}, []);
// ...
}
I am calling router.push
here. You could also call router.replace
, this would replace the current route with your /user
page rather than pushing a new entry into the window's history object.
Upvotes: 1