I am using react-router-dom version 7.0.1.
I have below code
import React from "react";
import Sidebar from "./../Sidebar/Sidebar";
//React Router's Outlet for rendering dynamic content
import { Outlet } from "react-router-dom";
import Box from "@mui/material/Box";
import Navbar from "../Header/Navbar";
import { useSelector } from "react-redux";
import { getToken } from "./../../../redux/auth/authSelectors";
export default function Main() {
const isAuthenticated = useSelector(getToken);
return (
<>
<Navbar />
<Box height={30}></Box>
<Box sx={{ display: "flex" }}>
{isAuthenticated && <Sidebar />}
{/* The Outlet will render the content based on the current route */}
<Outlet />
</Box>
{/* <Footer /> */}
</>
);
}
// src/routes/RoutesComponent.js
import React from "react";
import {
BrowserRouter as Router,
Switch,
Route,
Routes,
} from "react-router-dom";
import FeatureRoutes from "./FeatureRoutes";
import PublicRoutes from "./PublicRoutes";
import CommonRoutes from "./CommonRoutes";
import NotFoundPage from "../pages/NotFoundPage/NotFoundPage";
import Main from "./../components/layouts/Main/Main";
const RoutesComponent = () => (
<Router>
<Routes>
{/* Main route is the parent route that renders the layout */}
<Route path="/" element={<Main />}>
{/* Nested routes */}
<Route path="/" element={<PublicRoutes />} /> {/* Public routes */}
<Route element={<CommonRoutes />} /> {/* Common routes */}
<Route element={<FeatureRoutes />} />{" "}
{/* Feature Routes (grouped by URL prefixes) */}
</Route>
<Route path="*" element={<NotFoundPage />} /> {/* Catch-all for 404 */}
</Routes>
</Router>
);
export default RoutesComponent;
// src/routes/PublicRoutes.js
import React, { Suspense, lazy } from "react";
import { Routes, Route } from "react-router-dom";
import SuspenseFallback from "./../components/widgets/SuspenseFallback";
const Home = lazy(() => import("./../pages/Home/Home"));
const LoginPage = lazy(() => import("./../pages/Auth/Login"));
const Register = lazy(() => import("./../pages/Auth/Register"));
const PublicRoutes = () => {
return (
<Suspense
fallback={<SuspenseFallback message="Loading..." type="progress" />}
>
<Routes>
{/* The index route will render Home by default inside the Main layout */}
<Route index element={<Home />} />
{/* Other routes will be rendered inside Main's Outlet */}
<Route path="login" element={<LoginPage />} />
<Route path="register" element={<Register />} />
{/* <Route path="about" element={<Pages.About />} />
<Route path="settings" element={<Pages.Settings />} /> */}
</Routes>
</Suspense>
);
};
export default PublicRoutes;
//src/routes/ProtectedRoute.js
import React from "react";
import { Route, Navigate } from "react-router-dom";
import { isAuthenticated, getUserRole } from "../utils/auth";
const ProtectedRoute = ({ element, roles, ...rest }) => {
// Check if user is authenticated and has required roles
const isAuthorized = isAuthenticated() && roles.includes(getUserRole());
return (
<Route
{...rest}
element={isAuthorized ? element : <Navigate to="/login" />}
/>
);
};
export default ProtectedRoute;
// src/routes/CommonRoutes.js
import React, { Suspense, lazy } from "react";
import { Routes, Route } from "react-router-dom";
import ProtectedRoute from "./ProtectedRoute";
import SuspenseFallback from "./../components/widgets/SuspenseFallback";
// Lazy load the dashboard component
const Dashboard = lazy(() => import("./../pages/Dashboard/Dashboard"));
const CommonRoutes = () => {
return (
<Suspense
fallback={<SuspenseFallback message="Loading..." type="progress" />}
>
<Routes>
{/* Dashboard Route - Accessible to user and admin */}
<ProtectedRoute
path="dashboard"
roles={["user", "admin"]}
element={<Dashboard />}
/>
{/* <ProtectedRoute
path="another-page"
roles={["admin"]}
element={<AnotherPage />}
/> */}
{/* More routes can be added here */}
</Routes>
</Suspense>
);
};
export default CommonRoutes;
// src/routes/FeatureRoutes/index.js
import React from "react";
import { Route, Routes } from "react-router-dom";
import UserRoutes from "./UserRoutes";
import ProductRoutes from "./ProductRoutes";
const FeatureRoutes = () => (
<Suspense
fallback={<SuspenseFallback message="Loading..." type="progress" />}
>
<Routes>
{/* Define the prefix for all user-related routes */}
<Route path="users/*" element={<UserRoutes />} />
{/* Define the prefix for all product-related routes */}
<Route path="products/*" element={<ProductRoutes />} />
</Routes>
</Suspense>
);
export default FeatureRoutes;
// src/routes/FeatureRoutes/UserRoutes.js
import React from "react";
import { Routes, Route } from "react-router-dom";
import UserProfile from "./UserProfile";
const UserRoutes = () => (
<>
{/* Grouping all routes under the "/user" prefix */}
{/* Protected Route for User Profile */}
<ProtectedRoute
exact
path="profile"
component={UserProfile}
roles={["user", "admin"]} // Only users and admins can access
/>
</>
);
export default UserRoutes;
So as mentioned in above code, RouteComponent is starting point of routes which can have PublicRoutes , CommonRoutes, FeatureRoutes etc are wrapped under Main Component. In FeatureRoutes, I have index.js file which includes routes of features like users, products etc using prefixes. PublicRoutes , CommonRoutes can have multiple paths/routes. So I don’t want to give any specific path in RoutesComponent. But it should render according to structure.
With above code structure only http://localhost:3000/
path which is in PublicRoutes file is working and loading Home component.
other paths for example:-
http://localhost:3000/login,
http://localhost:3000/register,
http://localhost:3000/dashboard,
http://localhost:3000/users/profile
etc are not working or showing NotFoundPage.
Whats going wrong in above code ? please help and guide.