I'm using Next.js 14.2 with the page directory. When I create a build and run npm start
, it opens a landing page with a login button using the <Link>
component. I also set prefetch={false}
in the login button. When I redirect to the login screen and enter all the correct values, it shows "login successful," but it does not redirect to the dashboard. I'm sharing the redirect code below.
import { useRouter } from 'next/router';
const router = useRouter();
useEffect(() => {
if (loggedin && localStorage?.getItem('token')) {
console.log("isReady", router.isReady);
router.push(ROUTE_NAMES.DASHBOARD);
}
}, [loggedin]);
When I check the console, isReady
is returning true
. Let me know where I'm wrong.
EDIT
I change a bit and put a condition of isReady
state when changing the route. But when i set the middleware I got stuck again it is not changing page.
if (NO_AUTH_ROUTES.includes(pathname)) {
return NextResponse.next();
} else if (isAuthenticate && AUTH_ROUTES.includes(pathname)) {
// Return to dashboard as it is in auth route
return NextResponse.redirect(new URL(ROUTE_NAMES.DASHBOARD, request.url));
} else if (!AUTH_ROUTES.includes(pathname)) {
// Check if the pathname is not in AUTH_ROUTES
// If token or isAuthenticate is missing, redirect to login
if (!isAuthenticate) {
return NextResponse.redirect(new URL(ROUTE_NAMES.LOGIN, request.url));
}
}
return NextResponse.next();
Solution: github.com/vercel/next.js/discussions/51782
You might encounter an issue where router.push() in Next.js doesn't redirect the user as expected after successful authentication when called from middleware. A potential fix for this is to refresh the router just before invoking router.push(). This seems to solve the issue, though the exact reason behind it isn't well-documented.
Here’s a code example:
// After successful authentication
router.refresh(); // Refresh the router state
router.push('/desired-url'); // Redirect the user to the desired URL
By calling router.refresh(), you force the router to update its state, which ensures that router.push() works as intended. This approach worked for me, and I hope it helps others facing the same issue.
Reference: https://github.com/vercel/next.js/discussions/51782#discussioncomment-6470680