skip to Main Content

"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


  1. The problem is with your logic in PrivateRoute. Change your PrivateRoute logic to check when the user is logged in and is going to /login route.

    const PrivateRoute = ({ children }) => {
        const { user, loading } = useContext(AuthContext);
        const location = useLocation();
    
        if (loading) {
            return <progress className="progress w-full "></progress>;
        }
    
        if (user?.email) {
            // If the user is authenticated, check if login route is called
            if (location.pathname === "/login") {
                return <Navigate to="/" replace />;
            }
            return children;
        }
    
        return <Navigate to="/login" state={{ from: location }} replace></Navigate>;
    };
    
    Login or Signup to reply.
  2. 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 of PrivateRoute in PublicRoute. This way it’s more maintainable and reusable than piling on different conditionals for public routes inside PrivateRoute component. Logic should be pretty simple. Something like below…

    const PublicRoute = ({ children }) => {
        const { user, loading } = useContext(AuthContext);
    
        if (loading) {
            return <progress className="progress w-full "></progress>;
        }
    
        if (user?.email) {
            return <Navigate to="/" replace />;
        }
    
        return children;
    };
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search