Steps to reproduce
RouteManager.jsx
import { ThemeContext } from "@emotion/react";
import CircularProgress from "@mui/material/CircularProgress";
import { UserContext } from "context/UserContext";
import Offline from "pages/public/Offline";
import { lazy, Suspense, useContext } from "react";
import { Route, Routes } from "react-router-dom";
import { ToastContainer } from "react-toastify";
const Private = lazy(() => import("./Private"));
const Public = lazy(() => import("./Public"));
export default function RouteManager() {
const userCntx = useContext(UserContext);
const themeContext = useContext(ThemeContext);
return (
<>
<Suspense fallback={<CircularProgress sx={{ mx: "auto", my: "50%" }} />}>
<Routes>
{
userCntx.isAuthenticated ? <Route path="/dashboard/*" element={<Private />} /> : null
}
<Route path="/offline/" element={<Offline />} />
<Route index path="/*" element={<Public />} />
</Routes >
<ToastContainer
autoClose={5000}
rtl={true}
pauseOnFocusLoss
draggable
pauseOnHover
theme={themeContext.isDarkMode ? "dark" : "light"}
/>
</Suspense>
</>
);
}
Private.jsx
import { Alert, Box, CircularProgress, useTheme } from '@mui/material';
import { PageContainer } from '@toolpad/core';
import { DashboardLayout } from '@toolpad/core/DashboardLayout';
import { ReactRouterAppProvider } from "@toolpad/core/react-router";
import urls from 'api/urls';
import logo from "assets/images/logo.png";
import useGetObj from "hooks/useGetObj";
import { lazy, useEffect, useState } from "react";
import { Route, Routes } from 'react-router-dom';
import get_pages from "utils/get_pages";
const Dashboard = lazy(() => import("pages/private/dashboard/MainDashboard"));
const Profile = lazy(() => import("pages/private/profile/Profile"));
const AddArticle = lazy(() => import("pages/private/Articles/AddArticle"));
const ArticleList = lazy(() => import("pages/private/Articles/ArticleList"));
const Users = lazy(() => import("pages/private/users/Users"));
const branding = {
homeUrl: "/",
logo: <img src={logo} alt="Logo" />,
title: "Website"
};
export default function Private() {
const theme = useTheme();
const [navigation, setNavigation] = useState([]);
const [user, isLoaded, error] = useGetObj({ url: `${urls.account}profile/` });
useEffect(() => {
if (isLoaded && !error && user) {
const pages = get_pages(user);
setNavigation(pages);
}
}, [user, isLoaded, error]);
if (!isLoaded) {
return <Box sx={{ mt: 20, textAlign: 'center' }}><CircularProgress /></Box>;
} else if ((isLoaded && user === null) || error) {
return (
<Box sx={{ mt: 20, textAlign: 'center', p: 5 }}>
<Alert severity='error'>
Error
</Alert>
</Box>
);
}
else if (isLoaded && !user.is_active) {
return (
<Box sx={{ mt: 20, textAlign: 'center', p: 5 }}>
<CircularProgress />
</Box>
);
} else {
return (
<ReactRouterAppProvider theme={theme} branding={branding} navigation={navigation} session={user} >
<DashboardLayout>
<PageContainer>
<Routes>
<Route path="/" exact index element={<Dashboard />} />
<Route path='profile/' element={<Profile />} />
{
user.is_superuser ?
<>
<Route path='article/' element={<AddArticle />} />
<Route path='article/add/' element={<AddArticle />} />
<Route path='article/list/' element={<ArticleList />} />
<Route path='users/' element={<Users />} />
</> : null
}
</Routes>
</PageContainer>
</DashboardLayout>
</ReactRouterAppProvider>
);
}
}
getPages.js
import CreateRoundedIcon from '@mui/icons-material/CreateRounded';
import DashboardIcon from '@mui/icons-material/Dashboard';
import NewspaperRoundedIcon from '@mui/icons-material/NewspaperRounded';
import PersonRoundedIcon from '@mui/icons-material/PersonRounded';
import SegmentRoundedIcon from '@mui/icons-material/SegmentRounded';
const Base_NAVIGATION = [
{
kind: 'header',
title: 'User Dashboard',
},
{
segment: 'dashboard',
pattern: 'dashboard(/)?',
title: 'Dashboard',
icon: <DashboardIcon />,
},
{
segment: 'dashboard/profile',
pattern: 'dashboard/profile(/)?',
title: 'Profile',
icon: <PersonRoundedIcon />,
},
];
export default function get_pages(user) {
const pages = Base_NAVIGATION;
if (user.is_superuser) {
pages.push(
{
kind: 'header',
title: 'Auther Dashboard',
},
{
segment: 'dashboard/article',
pattern: 'dashboard/article(/)?',
title: 'Articles',
icon: <NewspaperRoundedIcon />,
children: [
{
segment: 'add',
pattern: 'dashboard/article/add(/)?', // Add full pattern
title: 'Add',
icon: <CreateRoundedIcon />
},
{
segment: 'list',
pattern: 'dashboard/article/list(/)?', // Add full pattern
title: 'List',
icon: <SegmentRoundedIcon />
},
]
},
);
return pages;
}
return pages;
}
Note: Just use dummy component for Route elements. It doesn't matter because they are empty screens like
function Untitled() {
return (
<div>Untitled</div>
)
}
export default Untitled;
Current behavior
Page doesn't shows up and says
Item not found in navigation: Add
invariant@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7730:15
getItemPath@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7028:41
./node_modules/@toolpad/core/esm/shared/navigation.js/hasSelectedNavigationChildren/<@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7044:33
hasSelectedNavigationChildren@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7037:26
./node_modules/@toolpad/core/esm/DashboardLayout/DashboardSidebarSubNavigation.js/DashboardSidebarSubNavigation/initialExpandedItemIds</<@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:5732:194
./node_modules/@toolpad/core/esm/DashboardLayout/DashboardSidebarSubNavigation.js/DashboardSidebarSubNavigation/initialExpandedItemIds<@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:5730:7
mountMemo@http://localhost:3000/static/js/bundle.js:46922:21
useMemo@http://localhost:3000/static/js/bundle.js:55131:16
./node_modules/react/cjs/react.development.js/exports.useMemo@http://localhost:3000/static/js/bundle.js:70415:32
DashboardSidebarSubNavigation@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:5727:69
react_stack_bottom_frame@http://localhost:3000/static/js/bundle.js:56014:18
renderWithHooks@http://localhost:3000/static/js/bundle.js:46224:38
updateFunctionComponent@http://localhost:3000/static/js/bundle.js:47917:17
beginWork@http://localhost:3000/static/js/bundle.js:48503:16
runWithFiberInDEV@http://localhost:3000/static/js/bundle.js:43995:125
performUnitOfWork@http://localhost:3000/static/js/bundle.js:50576:93
workLoopSync@http://localhost:3000/static/js/bundle.js:50469:55
renderRootSync@http://localhost:3000/static/js/bundle.js:50453:7
performWorkOnRoot@http://localhost:3000/static/js/bundle.js:50217:42
performSyncWorkOnRoot@http://localhost:3000/static/js/bundle.js:51181:22
flushSyncWorkAcrossRoots_impl@http://localhost:3000/static/js/bundle.js:51100:306
flushSpawnedWork@http://localhost:3000/static/js/bundle.js:50878:36
commitRoot@http://localhost:3000/static/js/bundle.js:50722:7
commitRootWhenReady@http://localhost:3000/static/js/bundle.js:50287:15
Also console log is
Uncaught Invariant Violation: Item not found in navigation: Add
invariant http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7730
getItemPath http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7028
node_modules toolpad/core/esm/shared/navigation.js/hasSelectedNavigationChildren/<@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7044
hasSelectedNavigationChildren http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7037
node_modules toolpad/core/esm/DashboardLayout/DashboardSidebarSubNavigation.js/DashboardSidebarSubNavigation/initialExpandedItemIds</<@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:5732
node_modules toolpad/core/esm/DashboardLayout/DashboardSidebarSubNavigation.js/DashboardSidebarSubNavigation/initialExpandedItemIds<@http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:5730
mountMemo http://localhost:3000/static/js/bundle.js:46922
useMemo http://localhost:3000/static/js/bundle.js:55131
useMemo http://localhost:3000/static/js/bundle.js:70415
DashboardSidebarSubNavigation http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:5727
react_stack_bottom_frame http://localhost:3000/static/js/bundle.js:56014
renderWithHooks http://localhost:3000/static/js/bundle.js:46224
updateFunctionComponent http://localhost:3000/static/js/bundle.js:47917
beginWork http://localhost:3000/static/js/bundle.js:48503
runWithFiberInDEV http://localhost:3000/static/js/bundle.js:43995
performUnitOfWork http://localhost:3000/static/js/bundle.js:50576
workLoopSync http://localhost:3000/static/js/bundle.js:50469
renderRootSync http://localhost:3000/static/js/bundle.js:50453
performWorkOnRoot http://localhost:3000/static/js/bundle.js:50217
performSyncWorkOnRoot http://localhost:3000/static/js/bundle.js:51181
flushSyncWorkAcrossRoots_impl http://localhost:3000/static/js/bundle.js:51100
flushSpawnedWork http://localhost:3000/static/js/bundle.js:50878
commitRoot http://localhost:3000/static/js/bundle.js:50722
commitRootWhenReady http://localhost:3000/static/js/bundle.js:50287
setTimeout handler*performWorkOnRoot http://localhost:3000/static/js/bundle.js:50264
performWorkOnRootViaSchedulerTask http://localhost:3000/static/js/bundle.js:51173
performWorkUntilDeadline http://localhost:3000/static/js/bundle.js:70529
js http://localhost:3000/static/js/bundle.js:70648
js http://localhost:3000/static/js/bundle.js:70755
factory http://localhost:3000/static/js/bundle.js:77884
__webpack_require__ http://localhost:3000/static/js/bundle.js:77239
fn http://localhost:3000/static/js/bundle.js:77500
hotRequire http://localhost:3000/static/js/bundle.js:77867
js http://localhost:3000/static/js/bundle.js:70770
factory http://localhost:3000/static/js/bundle.js:77884
__webpack_require__ http://localhost:3000/static/js/bundle.js:77239
fn http://localhost:3000/static/js/bundle.js:77500
hotRequire http://localhost:3000/static/js/bundle.js:77867
js http://localhost:3000/static/js/bundle.js:53775
js http://localhost:3000/static/js/bundle.js:56776
factory http://localhost:3000/static/js/bundle.js:77884
__webpack_require__ http://localhost:3000/static/js/bundle.js:77239
fn http://localhost:3000/static/js/bundle.js:77500
hotRequire http://localhost:3000/static/js/bundle.js:77867
js http://localhost:3000/static/js/bundle.js:57000
factory http://localhost:3000/static/js/bundle.js:77884
__webpack_require__ http://localhost:3000/static/js/bundle.js:77239
fn http://localhost:3000/static/js/bundle.js:77500
hotRequire http://localhost:3000/static/js/bundle.js:77867
js http://localhost:3000/static/js/bundle.js:76668
factory http://localhost:3000/static/js/bundle.js:77884
__webpack_require__ http://localhost:3000/static/js/bundle.js:77239
<anonymous> http://localhost:3000/static/js/bundle.js:78488
<anonymous> http://localhost:3000/static/js/bundle.js:78490
[vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js:7730:15](http://localhost:3000/static/js/vendors-node_modules_mui_icons-material_esm_CreateRounded_js-node_modules_mui_icons-material_-797098.chunk.js)
An error occurred in the <DashboardSidebarSubNavigation> component.
Consider adding an error boundary to your tree to customize error handling behavior.
Visit https://react.dev/link/error-boundaries to learn more about error boundaries.
Expected behavior
Show pages under /dashboard/ path instead of root or anything else without any error.
Context
I have 2 routes.
- Public
- Private
Public URLs are under root (/) and private URL which needs authentication and are under dashboard (/dashboard).
get_pages is responsible for getting dashboard pages according user accesses and permissions.
RouteManager is responsible for checking for users authentication and let them to access private pages
I tried many approaches to put side navigation's in dashboard under /dashboard/ in this scenario but either they went under root url (when I change url/pattern in get_pages) or just not shows up when I put location prop to Routes in Private.jsx.
Your environment
Firefox
npx @mui/envinfo
System:
OS: Linux 6.14 Ubuntu 24.04.3 LTS 24.04.3 LTS (Noble Numbat)
Binaries:
Node: 22.13.0 - ~/.nvm/versions/node/v22.13.0/bin/node
npm: 10.9.2 - ~/.nvm/versions/node/v22.13.0/bin/npm
pnpm: Not Found
Browsers:
Chrome: Not Found
npmPackages:
@emotion/react: ^11.14.0 => 11.14.0
@emotion/styled: ^11.14.1 => 11.14.1
@mui/core-downloads-tracker: 7.3.1
@mui/icons-material: 7.3.1 => 7.3.1
@mui/material: 7.3.1 => 7.3.1
@mui/private-theming: 7.3.1
@mui/styled-engine: 7.3.1
@mui/styled-engine-sc: 7.3.1 => 7.3.1
@mui/system: 7.3.1
@mui/types: 7.4.5
@mui/utils: 7.3.1
@mui/x-data-grid: 8.10.1
@mui/x-date-pickers: ^8.10.0 => 8.10.0
@mui/x-internals: 8.10.0
@mui/x-virtualizer: 0.1.2
@toolpad/core: ^0.16.0 => 0.16.0
@toolpad/utils: 0.16.0
react: ^19.1.1 => 19.1.1
react-dom: ^19.1.1 => 19.1.1
styled-components: ^6.1.19 => 6.1.19
typescript: ^5.9.2 => 5.9.2
Search keywords: navigation, react
Steps to reproduce
RouteManager.jsx
Private.jsx
getPages.js
Note: Just use dummy component for
Routeelements. It doesn't matter because they are empty screens likeCurrent behavior
Page doesn't shows up and says
Also console log is
Expected behavior
Show pages under
/dashboard/path instead of root or anything else without any error.Context
I have 2 routes.
Public URLs are under root (
/) and private URL which needs authentication and are under dashboard (/dashboard).get_pagesis responsible for getting dashboard pages according user accesses and permissions.RouteManageris responsible for checking for users authentication and let them to access private pagesI tried many approaches to put side navigation's in dashboard under
/dashboard/in this scenario but either they went under root url (when I change url/pattern in get_pages) or just not shows up when I putlocationprop toRoutesin Private.jsx.Your environment
Firefox
npx @mui/envinfoSearch keywords: navigation, react