2

I need to define user pages (Home, Cows, Reports, ...) once and make them accessible to AppUser + Admin under "/" with UserLayout, and also accessible to Admin under "/admin/user/*" but rendered inside AdminLayout. When I try to reuse the same route array in both places, I sometimes get UserLayout showing for "/admin/user/" or matching conflicts due to absolute vs relative paths. I'm looking for an idiomatic pattern to mount the same relative child routes under two parents (two layouts) without duplication and without layout leaks.

I mounted user pages only under "/" inside UserLayout, guarded for both roles (AppUser + Admin). I mounted admin-only pages under "/admin/*" inside AdminLayout, guarded for Admin only.

Router (what I did):

router.jsx (essentials)

{
 element: <RequireAuth />,
 children: [
 {
 path: "/",
 element: <UserLayout />,
 children: [
 {
 element: <RequireRole allowed={[Roles.AppUser, Roles.Admin]} />,
 children: [
 { path: "/", element: <Home /> },
 { path: "/cows", element: <AnimalManagement /> },
 // ...other user pages under "/"
 ],
 },
 ],
 },
 {
 path: "/admin",
 element: <RequireRole allowed={[Roles.Admin]} />,
 children: [
 {
 path: "/admin",
 element: <AdminLayout />,
 children: [
 { path: "/admin/dashboard", element: <AdminDashboard /> },
 // ...other admin-only pages under "/admin"
 ],
 },
 ],
 },
 ],
}

Expectation:

When an Admin clicks user pages from the admin sidebar, I want those pages to render inside AdminLayout (so the admin shell/Sidebar stays visible), even though the same pages are also available at "/" for both roles.

Actual result:

Because user pages exist only under "/", navigating to them shows UserLayout, not AdminLayout. I’m looking for an React-Router/React-Router-DOM v6 pattern to mount the same user routes under "/admin/user/*" (alias) so they render inside AdminLayoutwithout duplicating the route definitions or breaking role guards.

Drew Reese
208k20 gold badges285 silver badges294 bronze badges
asked Oct 15, 2025 at 21:01
5
  • Is the problem you are trying to solve here that you want to only define routes once and use under two parent routes, or are you trying to only reference routed components once, or something else? It would be helpful if you could update your minimal reproducible example to be more representative of what you are trying to accomplish because as-is it's unclear what exactly you are trying to render, and where (or where not) you want to render it. Commented Oct 15, 2025 at 21:07
  • FWIW, there should be no issue in defining whatever routes you want/need under any parent route. Commented Oct 15, 2025 at 21:08
  • When I’m logged in as Admin and navigate to a user page (which is allowed in my app), the router mounts UserLayout (because those routes live under /). So the AdminLayout (sidebar/shell) disappears. That’s logical given my current router, but I’m looking for a better code structure so an admin can browse the same user pages without leaving AdminLayout. Commented Oct 15, 2025 at 21:17
  • This happens because the user routes are nested under the root path (/) and the admin routes are nested under /admin. When I navigate to a user URL under /, React Router mounts the UserLayout branch, so the AdminLayout (which only exists under /admin) is unmounted and disappears. Commented Oct 15, 2025 at 21:20
  • Instead of complex object you can try my npm react-next-router. Simple folder based route like next js app router. Support Layout and group layout concept also. You can see example here also i just wrapped app router concept in react router Commented Nov 17, 2025 at 6:44

1 Answer 1

2

If I am understanding your question correctly, you are trying to render a set of "common" routes both under the root "/" path and also under the "/admin" path.

The first main issue I see in your router definition is that you are specifying absolute route paths everywhere. This makes it incredibly difficult, probably impossible, to allow using the routes anywhere but where they exactly match and specify. You should be using relative paths. E.G. paths that do not start with the "/" character. This will allow you to move a route around anywhere and it will always match relative to its parent route.

A second issue is defining paths on your layout routes. While this is perfectly fine and can work in most cases, you will typically want to avoid adding a path prop to your layout routes as you want them to typically only enforce UI layout and not participate in routing.

Here is my suggestion:

  1. Create a definition of your "common routes", i.e. the routes you wish to render under multiple parent routes.
const commonUserAndAdminRoutes = [
 { path: "cows", element: <AnimalManagement /> },
 { path: "sheep", element: /* .... */ },
 { path: "pigs", element: /* .... */ },
 // ...etc...
];
  1. Update the router to use relative route paths and spread in the common routes where you want/need them.
const router = createBrowserRouter([
 {
 // pathless route!
 element: <RequireAuth />,
 children: [
 {
 // pathless route!
 element: <RequireRole allowed={[Roles.AppUser, Roles.Admin]} />,
 children: [
 {
 // pathless route!
 element: <UserLayout />,
 children: [
 // index route matches "/"
 { index: true, element: <Home /> },
 // common routes match relative to "/"
 ...commonUserAndAdminRoutes,
 // ...other user pages under "/"
 ],
 },
 ],
 },
 {
 path: "admin",
 element: <RequireRole allowed={[Roles.Admin]} />,
 children: [
 {
 // pathless route!
 element: <AdminLayout />,
 children: [
 // index route matches "/admin" and redirects to "/admin/dashboard"
 { index: true, element: <Navigate to="dashboard" replace /> },
 // matches "/admin/dashboard"
 { path: "dashboard", element: <AdminDashboard /> },
 // common routes match relative to "/admin"
 ...commonUserAndAdminRoutes,
 // ...other admin-only pages under "/admin"
 ],
 },
 ],
 },
 ],
 },
]);

If you want admins to see the same AdminLayout on "/" and other non-"/admin" routes (instead of UserLayout) then my suggestion would be create a dynamic layout route component that renders either of UserLayout or AdminLayout depending on the role or whatever criteria you need.

Example:

const UserOrAdminLayout = () => {
 const isAdmin = /* compute this */;
 return isAdmin
 ? <AdminLayout />
 : <UserLayout />;
};
const router = createBrowserRouter([
 {
 element: <RequireAuth />,
 children: [
 {
 element: <RequireRole allowed={[Roles.AppUser, Roles.Admin]} />,
 children: [
 {
 element: <UserOrAdminLayout />,
 children: [
 { index: true, element: <Home /> },
 { path: "/cows", element: <AnimalManagement /> },
 // ...other user pages under "/"
 ],
 },
 ],
 },
 {
 path: "admin",
 element: <RequireRole allowed={[Roles.Admin]} />,
 children: [
 {
 element: <AdminLayout />,
 children: [
 { index: true, element: <Navigate to="dashboard" replace /> },
 { path: "dashboard", element: <AdminDashboard /> },
 // ...other admin-only pages under "/admin"
 ],
 },
 ],
 },
 ],
 },
]);
answered Oct 15, 2025 at 22:05
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.