"If the user is already authenticated, I aim to restrict their access to the login page. Currently, when attempting to navigate to ‘/login’ while already logged in, the system still redirects to ‘/login’. However, my intention is to prevent this redirection and maintain the user at their current authenticated state
route.jsx
import { createBrowserRouter } from "react-router-dom";
import Main from "../Layout/Main";
import Home from "../Components/Home/Home/Home";
import Login from "../Components/Login/Login";
import SignUp from "../Components/SignUp/SignUp";
import Checkout from "../Components/Checkout/Checkout";
import Bookings from "../Components/Bookings/Bookings";
import PrivateRoute from "./PrivateRoute";
const router = createBrowserRouter([
{
path: "/",
element: <Main></Main>,
children: [
{
path: "/",
element: <Home></Home>,
},
{
path: "/login",
element: <Login></Login>,
},
{
path: "/signup",
element: <SignUp></SignUp>,
},
{
path: "/bookings",
element: (
<PrivateRoute>
<Bookings></Bookings>
</PrivateRoute>
),
},
{
path: "/services/:id",
element: <PrivateRoute><Checkout></Checkout></PrivateRoute>,
loader: ({ params }) =>
fetch(`http://localhost:5000/services/${params.id}`),
},
],
},
]);
export default router;
privateroute.jsx:
import { useContext } from "react";
import { AuthContext } from "../providers/AuthProvider";
import { Navigate, useLocation } from "react-router-dom";
const PrivateRoute = ({ children }) => {
const { user, loading } = useContext(AuthContext);
const location = useLocation();
if (loading) {
return <progress className="progress w-full "></progress>;
}
if (user?.email) {
return children;
}
return <Navigate to="/login" state={{from:location}} replace></Navigate>;
};
export default PrivateRoute;
I tried this, but I can still access the ‘/login’ page even when I’m logged in.
import { useContext } from "react";
import { AuthContext } from "../providers/AuthProvider";
import { Navigate, useLocation } from "react-router-dom";
const PrivateRoute = ({ children }) => {
const { user, loading } = useContext(AuthContext);
const location = useLocation();
if (loading) {
return <progress className="progress w-full "></progress>;
}
if (user?.email) {
return children;
}
if (user?.email && location.pathname === "/login") {
return <Navigate to="/" replace />;
}
return <Navigate to="/login" state={{ from: location }} replace></Navigate>;
};
export default PrivateRoute;
2
Answers
The problem is with your logic in
PrivateRoute
. Change yourPrivateRoute
logic to check when the user is logged in and is going to/login
route.A pattern I used to follow was to have
PublicRoute
component for public routes, like a landing page, or login/sign-up page in this case. You could basically do the opposite logic ofPrivateRoute
inPublicRoute
. This way it’s more maintainable and reusable than piling on different conditionals for public routes insidePrivateRoute
component. Logic should be pretty simple. Something like below…