Learn how to build a robust dashboard navigation UI by integrating sidebar layouts, private route guards, and authentication state in React.
Previously in this course, we explored the mechanics of Introduction to React Router: Building Multi-Page SPAs and learned how to secure specific views using Protected Routes for Authenticated Views in React. Now, we will synthesize these concepts into a production-ready dashboard shell.
A professional dashboard isn't just a collection of pages; it’s a cohesive navigation experience. Our goal today is to build a persistent sidebar layout that remains visible while the main content area changes, all while ensuring that our navigation links reflect the user's current authentication state.
When building a dashboard, you want a persistent layout. Instead of re-rendering the sidebar on every page transition, we use Nested Routes and Layouts: Mastering React Router UI Design to wrap our sub-pages.
The layout component acts as the "shell." It contains the static UI—like your sidebar and top navigation—and uses the <Outlet /> component to render the specific page content.
The sidebar needs to be aware of the current route to highlight active links. We use the NavLink component from react-router-dom, which automatically applies an active class to the link matching the current URL.
JSXimport { NavLink } from CE9178">'react-router-dom'; const Sidebar = () => { return ( <nav className="sidebar"> <ul> <li><NavLink to="/dashboard/overview">Overview</NavLink></li> <li><NavLink to="/dashboard/settings">Settings</NavLink></li> </ul> </nav> ); };
A common requirement in dashboard UI development is showing different menu items based on the user's session. Since we have already implemented Handling Authentication State with React Context API, we can consume that state directly in our navigation.
Here is how we integrate the Auth state into our layout:
JSXimport { Outlet } from CE9178">'react-router-dom'; import { useAuth } from CE9178">'../context/AuthContext'; import Sidebar from CE9178">'./Sidebar'; export const DashboardLayout = () => { const { user, logout } = useAuth(); return ( <div className="dashboard-container"> <Sidebar /> <main className="content"> <header> <span>Welcome, {user?.name}</span> <button onClick={logout}>Logout</button> </header> {/* The child routes render here */} <Outlet /> </main> </div> ); };
With the layout in place, we define our route configuration. We want to ensure that all /dashboard/* routes are protected. By nesting these inside a parent route that uses our ProtectedRoute component, we centralize the security logic.
JSX<Routes> <Route element={<ProtectedRoute />}> <Route path="/dashboard" element={<DashboardLayout />}> <Route path="overview" element={<Overview />} /> <Route path="settings" element={<Settings />} /> </Route> </Route> </Routes>
By placing the DashboardLayout inside the ProtectedRoute, the layout itself only renders if the user is authenticated. This prevents the sidebar from flickering or rendering for unauthorized users.
Your task is to refine the DashboardLayout navigation.
LogoutButton component that uses Mastering Programmatic Navigation with useNavigate in React to redirect the user to the login page immediately after the logout() function is called.Sidebar to only display the "Admin" link if user.role === 'admin'.<Outlet /> component inside your DashboardLayout. Without it, React Router doesn't know where to inject the child components.We have successfully moved from basic routing to a structural dashboard pattern. By combining the Outlet for layout persistence, NavLink for active state, and our existing Auth Context for security, we've created a robust foundation. Your dashboard is now a true SPA where navigation feels instant and secure.
Up next: We will begin moving away from static mock data and start managing the Asynchronous Data Lifecycle to fetch real metrics from your API.
Learn how to use the useNavigate hook in React Router to trigger navigation on events, handle redirects, and manage complex user flows in your dashboard.
Read moreLearn how to use nested routes and the Outlet component in React Router to build consistent page layouts, reduce code duplication, and improve UI design.
Building the Dashboard Navigation Structure
Synchronizing Client and Server State
Integrating Live Data into the Dashboard
Error Handling and Loading UI
Controlled vs Uncontrolled Components
Real-time Form Validation
Schema-based Validation with Zod
Handling Multi-step Forms
Optimizing Form Submissions
Performance Profiling with React DevTools
Refactoring for Scalability
Finalizing Dashboard Data Flow
Deploying the Application
Advanced Hook Composition
Implementing Middleware for State
Advanced Context Patterns
Router Loaders and Data Prefetching
Complex Route Guards
Handling Large Datasets in UI
Testing Hooks and Components
Managing Global Modals
Implementing Keyboard Shortcuts
Optimizing Asset Loading
Internationalization Basics
Managing WebSocket Connections