Here is the link to sandbox: https://codesandbox.io/s/react-router-dom-nested-routes-z9hy45
I'm using react-router-dom and define my routes in separate file, I want to use nested routes with outlet for protected routes
<Routes>
<Route path="/" element={<About />} />
<Route path="/login" element={<Login />} />
<Route element={<ProtectedLayout />}>
<Route path="/user" element={<User />} />
</Route>
</Routes>
This works exactly how I want, but I want to declare this logic in routes.js file and just use
const routes = useRoutes(publicRoutes)
const protectedRoutes = useRoutes(privateRoutes)
return (
<div>
{router}
// So what I want is to protectedRoutes be wrapped by ProtectedLayout somehow in routes.js
{protectedRoutes}
</div>
Map the public/private routes to JSX, and import & render these in App
.
Example:
routes.js
import { Route } from "react-router-dom";
import { Home } from "./components/Home";
import { Login } from "./components/Login";
import { User } from "./components/User";
export const publicRoutes = [
{
path: "/",
element: <Home />
},
{
path: "/login",
element: <Login />
}
].map((props) => <Route {...props} />);
export const privateRoutes = [
{
path: "/user",
element: <User />
}
].map((props) => <Route {...props} />);
App.js
import "./styles.css";
import { Route, Routes } from "react-router-dom";
import { ProtectedLayout } from "./components/ProtectedLayout";
import { privateRoutes, publicRoutes } from "./routes";
export default function App() {
return (
<div className="App">
<Routes>
{publicRoutes}
<Route element={<ProtectedLayout />}>
{privateRoutes}
</Route>
</Routes>
</div>
);
}
You could also instead use a Data router and pass the routes in the configuration object.
routes.js
import { Home } from "./components/Home";
import { Login } from "./components/Login";
import { User } from "./components/User";
export const publicRoutes = [
{
path: "/",
element: <Home />
},
{
path: "/login",
element: <Login />
}
];
export const privateRoutes = [
{
path: "/user",
element: <User />
}
];
App.js
import "./styles.css";
import { createBrowserRouter, RouterProvider } from "react-router-dom";
import { ProtectedLayout } from "./components/ProtectedLayout";
import { privateRoutes, publicRoutes } from "./routes";
const router = createBrowserRouter([
...publicRoutes,
{
element: <ProtectedLayout />,
children: [...privateRoutes]
}
])
export default function App() {
return (
<div className="App">
<RouterProvider router={router} />
</div>
);
}