I have multiple pages that have the navbar and the sidebar as component in my app.js and I have another page such as my login page that does not have this navbar and sidebar. How do I make the routing using react-router
so that the login page will be entirely a different route page without the sidebar and navbar, while the other multiple pages will have the sidebar and navbar on the app.js?
Below is what I have done so far but the dashboard page inside the route is not displaying.
app.js
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
function App() {
return (
<Router>
<Routes>
<Route path="/login" element={<Login />} />
<Route path='/' element={(
<>
<Container>
<SideBar />
<Main>
<Navbar />
<Wrapper>
<Route path='landing' element={<Dashboard/>} />
<Route path='pricing' element={<Price/>} />
</Wrapper>
</Main>
</Container>
</>
)}/>
</Routes>
</Router>
);
}
export default App;
Right now the whole page is not working again. I am currently getting the is error message:
Uncaught runtime errors:
×
ERROR
A <Route> is only ever to be used as the child of <Routes> element, never rendered directly. Please wrap your <Route> in a <Routes>.
at invariant (http://localhost:3000/static/js/bundle.js:17236:11)
at Route (http://localhost:3000/static/js/bundle.js:66637:78)
at renderWithHooks (http://localhost:3000/static/js/bundle.js:51633:22)
at mountIndeterminateComponent (http://localhost:3000/static/js/bundle.js:54919:17)
at beginWork (http://localhost:3000/static/js/bundle.js:56215:20)
at HTMLUnknownElement.callCallback (http://localhost:3000/static/js/bundle.js:41225:18)
at Object.invokeGuardedCallbackDev (http://localhost:3000/static/js/bundle.js:41269:20)
at invokeGuardedCallback (http://localhost:3000/static/js/bundle.js:41326:35)
at beginWork$1 (http://localhost:3000/static/js/bundle.js:61200:11)
at performUnitOfWork (http://localhost:3000/static/js/bundle.js:60447:16)
Is there a better approach to this?
The issue is that you are trying to render descendent routes that are not wrapped in a Routes
component.
Wrap the descendent routes in the Routes
component and ensure the parent route appends the "*"
wildcard matcher to the end of its path so all descendent routes can also be matched and rendered.
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
function App() {
return (
<Router>
<Routes>
<Route path="/login" element={<Login />} />
<Route
path="/*"
element={(
<Container>
<SideBar />
<Main>
<Navbar />
<Wrapper>
<Routes>
<Route path='landing' element={<Dashboard />} />
<Route path='pricing' element={<Price/>} />
</Routes>
</Wrapper>
</Main>
</Container>
)}
/>
</Routes>
</Router>
);
}
export default App;
You could alternatively create a layout route component that renders an Outlet
for nested routes to render their content into.
Example:
import {
BrowserRouter as Router,
Routes,
Route,
Outlet
} from 'react-router-dom';
const Layout = () => (
<Container>
<SideBar />
<Main>
<Navbar />
<Wrapper>
<Outlet />
</Wrapper>
</Main>
</Container>
);
function App() {
return (
<Router>
<Routes>
<Route path="/login" element={<Login />} />
<Route path="/" element={<Layout />}>
<Route path='landing' element={<Dashboard />} />
<Route path='pricing' element={<Price/>} />
</Route>
</Routes>
</Router>
);
}
export default App;