React Mastery / Routing (React Router)

Nested Routes and Layouts

🧠 Why Nested Routes?

In real apps:

  • Many pages share common UI

  • Example:

    • Dashboard sidebar

    • Header

    • Footer

Instead of repeating this UI on every page, we use layout routes with nested routing.


πŸ”€ What Is a Nested <Route>?

A route inside another route.

/dashboard
/dashboard/profile
/dashboard/settings

All these pages:

  • Share the same layout

  • Only the inner content changes


πŸ“¦ What Is a Layout Component?

  • A normal React component

  • Contains shared UI (sidebar, navbar)

  • Uses <Outlet /> to render child routes


πŸ”Œ What Is <Outlet />?

  • A placeholder component

  • Tells React Router where to render child routes

πŸ“Œ Without <Outlet />, nested routes will not render.


πŸ§ͺ Basic Example (Concept)

<Route path="/dashboard" element={<DashboardLayout />}>
  <Route path="profile" element={<Profile />} />
  <Route path="settings" element={<Settings />} />
</Route>

πŸ‘‰ Code Explanation

  • /dashboard is the parent route

  • DashboardLayout renders for all /dashboard/* URLs

  • profile and settings are nested (child) routes

  • Child paths are relative, not absolute

  • Final URLs become:

    • /dashboard/profile

    • /dashboard/settings

  • Profile and Settings render inside <Outlet />

  • DashboardLayout must contain <Outlet />

  • Shared UI (sidebar/header) stays the same, only content changes


πŸ“ Recommended Folder Structure

src/
 β”œβ”€ layouts/
 β”‚   └─ DashboardLayout.jsx
 β”œβ”€ pages/
 β”‚   β”œβ”€ DashboardHome.jsx
 β”‚   β”œβ”€ Profile.jsx
 β”‚   └─ Settings.jsx
 β”œβ”€ App.jsx

πŸ› οΈ Hands-On: Dashboard Layout

src/layouts/DashboardLayout.jsx

import { NavLink, Outlet } from 'react-router-dom';

function DashboardLayout() {
  return (
    <div style={{ display: 'flex' }}>
      {/* Sidebar */}
      <aside style={{ width: '200px' }}>
        <nav>
          <NavLink to="" end>Home</NavLink><br />
          <NavLink to="profile">Profile</NavLink><br />
          <NavLink to="settings">Settings</NavLink>
        </nav>
      </aside>

      {/* Main Content */}
      <main style={{ padding: '20px' }}>
        <Outlet />
      </main>
    </div>
  );
}

export default DashboardLayout;

πŸ‘‰ Code Explanation

  • DashboardLayout is a layout component for dashboard pages

  • Uses flex layout to place sidebar and content side by side

  • <aside> contains the sidebar navigation

  • NavLink is used for navigation with active state support

  • to="" end points to /dashboard (dashboard home)

  • to="profile" navigates to /dashboard/profile

  • to="settings" navigates to /dashboard/settings

  • <Outlet /> is the placeholder where nested routes render

  • Sidebar stays the same; only <Outlet /> content changes

πŸ§‘β€πŸ’» Create Nested Pages

src/pages/DashboardHome.jsx

function DashboardHome() {
  return <h2>Dashboard Home</h2>;
}

export default DashboardHome;

src/pages/Profile.jsx

function Profile() {
  return <h2>Profile Page</h2>;
}

export default Profile;

src/pages/Settings.jsx

function Settings() {
  return <h2>Settings Page</h2>;
}

export default Settings;

πŸ”— Define Nested Routes (App.jsx)

import { Routes, Route } from 'react-router-dom';
import DashboardLayout from './layouts/DashboardLayout';
import DashboardHome from './pages/DashboardHome';
import Profile from './pages/Profile';
import Settings from './pages/Settings';

function App() {
  return (
    <Routes>
      <Route path="/dashboard" element={<DashboardLayout />}>
        <Route index element={<DashboardHome />} />
        <Route path="profile" element={<Profile />} />
        <Route path="settings" element={<Settings />} />
      </Route>
    </Routes>
  );
}

export default App;

πŸ‘‰ Code Explanation

  • Imports Routes and Route for defining app routes

  • /dashboard is the parent route

  • DashboardLayout is rendered for all /dashboard/* paths

  • Nested routes share the same dashboard layout

  • index route loads when URL is exactly /dashboard

  • DashboardHome is the default dashboard page

  • profile route loads at /dashboard/profile

  • settings route loads at /dashboard/settings

  • Child components render inside <Outlet /> in DashboardLayout

  • No page reload happens during navigation


🧠 Important Concepts

index Route

<Route index element={<DashboardHome />} />
  • Loads when visiting /dashboard

  • Acts as the default child route


πŸ“Š URL β†’ Render Mapping

URL

Layout

Page

/dashboard

DashboardLayout

DashboardHome

/dashboard/profile

DashboardLayout

Profile

/dashboard/settings

DashboardLayout

Settings


⚠️ Common Mistakes

  • ❌ Forgetting <Outlet />

  • ❌ Using absolute paths inside nested routes

  • ❌ Not using index for default page

  • ❌ Duplicating layout UI across pages


βœ… Best Practices

  • Keep layouts simple and reusable

  • Use nested routes for:

    • Dashboards

    • Admin panels

    • Settings pages

  • Separate layouts and pages folders