React Router Setup with Dynamic Routes, Layouts, and Protected Pages
App.tsx
tsx
import {BrowserRouter, Route, Routes} from "react-router-dom";
import ProtectedRoute from "./auth/ProtectedRoute";
import Layout from "./layouts/Layout";
import Dashboard from "./pages/app/dashboard/Dashboard";
import Home from "./pages/app/home/Home";
import Login from "./pages/auth/login/Login";
function App() {
const routes = [
{
path: "/",
layout: Layout,
children: [{path: "", component: <Home />, protected: false}],
},
{
path: "/login",
component: <Login />,
protected: false,
},
{
path: "/dashboard",
component: <Dashboard />,
protected: true,
},
];
return (
<BrowserRouter>
<Routes>
{routes.map((item, index) => {
// If there's a layout, nest children under it
if (item.layout) {
const Layout = item.layout;
return (
<Route key={index} path={item.path} element={<Layout />}>
{item.children.map((child, j) => {
const element = child.protected ? (
<ProtectedRoute>{child.component}</ProtectedRoute>
) : (
child.component
);
return (
<Route
key={j}
index={child.path === ""}
path={child.path !== "" ? child.path : undefined}
element={element}
/>
);
})}
</Route>
);
}
// No layout route
const element = item.protected ? (
<ProtectedRoute>{item.component}</ProtectedRoute>
) : (
item.component
);
return <Route key={index} path={item.path} element={element} />;
})}
</Routes>
</BrowserRouter>
);
}
export default App;
ProtectedRouter.tsx
tsx
import type {ReactNode} from "react";
import {Navigate} from "react-router-dom";
const isAuthenticated = () => {
// Replace with your actual auth logic
return localStorage.getItem("token") !== null;
};
const ProtectedRoute: React.FC<{children: ReactNode}> = ({children}) => {
return isAuthenticated() ? children : <Navigate to="/login" replace />;
};
export default ProtectedRoute;