skip to Main Content

After implemented Private Route I keep getting this error.

The problem appears when Im trying to get to the Profile page that nested in the .

App.js

import './App.css';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import LoginPage from './pages/LoginPage';
import SignUpPage from './pages/SignUpPage';
import ProfilePage from './pages/ProfilePage';
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
import AdditionalItemPage from './pages/AdditionalItemPage';
import ReturnOfVehiclePage from './pages/ReturnOfVehiclePage';
import PolicyPage from './pages/PolicyPage';
import CarPage from './pages/CarPage';
import CarListPage from './pages/CarsListPage';
import NavBar from './NavBar';
import Footer from './Footer';
import NotFoundPage from './pages/NotFoundPage';
import { PrivateRoute } from './auth/PrivateRoute';

function App() {
  return (
    <BrowserRouter>
      <div className="App">
        <NavBar />
        <div>
          <Routes>
            <Route path="/" element={<HomePage />} />
            <Route path="/login" element={<LoginPage />} />
            <Route path="/signup" element={<SignUpPage />} />
            <Route path="/about" element={<AboutPage />} />
            <Route path="/cars" element={<CarListPage />} />
            <Route path="/cars/:carId" element={<CarPage />} />
            <Route path="/additional-item" element={<AdditionalItemPage />} />
            <Route path="/return-vehicle" element={<ReturnOfVehiclePage />} />
            <Route path="/policy" element={<PolicyPage />} />
            <Route
              path="/profile"
              element={
                <PrivateRoute>
                  <ProfilePage />
                </PrivateRoute>
              }
            />
            <Route path="*" element={<NotFoundPage />} />
          </Routes>
        </div>
        <Footer />
      </div>
    </BrowserRouter>
  );
}

export default App;

PrivateRoute.js comp

import { Route, Navigate } from 'react-router-dom';
import { useUser } from './useUser';

export const PrivateRoute = (props) => {
  const user = useUser();

  if (!user) return <Navigate to="/login" />;

  return <Route {...props} />;
};

I’ve already tried to wrap everyting I though of in the
The actual Profile paga into Routes
The PrivteRoute into Routes
The Route into another Routes
Creating another Routes, separeted with the 1st one.

If remove PrivateRoute, everything works fine but it s not the solution I’m looking for.

2

Answers


  1. The error message is accurate in that a Route must be directly placed within a Routes wrap. To get around this, simply create a 2nd top-level Routes wrap and move the Route logic out of your PrivateRoute.tsx file.

    Consider this example sandbox I created with some slight modifications to your code. You can switch user to false/true to see how the /profile private route reacts as expected.

    Here’s the bare-bones implementation:

    App.tsx

    import { BrowserRouter, Route, Routes } from "react-router-dom";
    import PrivateRoutes from "./PrivateRoutes";
    
    function App() {
      return (
        <BrowserRouter>
          <div className="App">
            <div>
              <Routes>
                <Route path="/" element={<div>Hello World</div>} />
              </Routes>
              <PrivateRoutes /> {/* <---- all private routes ---- */}
            </div>
          </div>
        </BrowserRouter>
      );
    }
    
    export default App;
    

    PrivateRoutes.tsx

    import { Route, Routes } from "react-router-dom";
    import PrivateRoute from "./PrivateRoute";
    
    export default function PrivateRoutes() {
      return (
        <Routes>
          <Route
            path="/profile"
            element={
              <PrivateRoute>
                <div>Private Profile</div>
              </PrivateRoute>
            }
          />
        </Routes>
      );
    }
    

    PrivateRoute.tsx

    import { ReactNode } from "react";
    import { Navigate } from "react-router-dom";
    
    interface PropsI {
      children: ReactNode;
    }
    
    export default function PrivateRoute({ children }: PropsI) {
      const user = false;
    
      if (!user) return <Navigate to="/fail" />;
    
      return <>{children}</>;
    }
    
    Login or Signup to reply.
  2. You just didn’t implement it properly , just change your PrivateRoute.js component like this :

    import {  Navigate } from 'react-router-dom';
    import { useUser } from './useUser';
    function PrivateRoute({ children }) {
      const user = useUser();
      return user ? children : <Navigate to="/login" />;
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search