How React Router Nested Routes Structure Applications
React Router Nested Routes create hierarchical URL structures that mirror your component hierarchy. They enable layout sharing, data loading optimization, and clean URL organization. Teams using nested routes report better code organization and improved user navigation patterns.
TL;DR
- Use
Outlet
to render child routes in parent layouts- Nested routes share layouts and enable data inheritance
- Create hierarchical URLs that match component structure
- Perfect for dashboards, admin panels, and content management
const result = process(data)
The Route Organization Challenge
Your application has grown complex with repeated layout code across different pages. Navigation changes require updating multiple components, and maintaining consistent styling across related pages becomes increasingly difficult as the app scales.
// Problematic: Repeated layout code across components
function UserProfilePage() {
const layout = {
header: 'User Management System',
content: 'Profile Content',
}
console.log('Profile page duplicates layout')
return layout
}
function UserSettingsPage() {
const duplicatedLayout = {
header: 'User Management System', // Duplicated!
content: 'Settings Content',
}
return duplicatedLayout
}
React Router nested routes eliminate duplication with shared layouts and hierarchical structure:
// React Router: Shared layouts with nested routes
const { Outlet } = require('react-router-dom')
const UserLayout = () => {
console.log('Shared layout initialized once')
return {
header: 'User Management System',
content: React.createElement(Outlet),
}
}
const routes = [
{
path: '/users',
element: React.createElement(UserLayout),
children: [{ path: 'profile', element: 'ProfileContent' }],
},
]
Best Practises
Use nested routes when:
- ✅ Building admin panels or dashboards with shared layouts
- ✅ Creating content management systems with hierarchical navigation
- ✅ Developing multi-step forms or wizards with common structure
- ✅ Organizing features that share similar UI patterns and data
Avoid when:
- 🚩 Simple applications with minimal page relationships
- 🚩 Each page has completely unique layouts and styles
- 🚩 Performance is critical and layout abstraction adds overhead
- 🚩 URL structure doesn't match your component hierarchy
System Design Trade-offs
Aspect | Nested Routes | Flat Route Structure |
---|---|---|
Code Reuse | Excellent - shared layouts | Poor - duplicated components |
URL Organization | Good - hierarchical structure | Poor - no relationship clarity |
Data Loading | Excellent - parallel parent/child | Poor - sequential loading |
Bundle Splitting | Easy - route-based chunks | Hard - manual optimization |
Layout Changes | Fast - single component update | Slow - multiple file updates |
Complexity | Medium - requires Outlet understanding | Low - straightforward rendering |
More Code Examples
❌ Flat route structure
// Flat route structure requiring layout duplication
const React = require('react')
const { createBrowserRouter } = require('react-router-dom')
function AdminDashboard() {
const layout = {
header: 'Admin Panel',
navigation: ['Dashboard', 'Users', 'Analytics'],
sidebar: ['Quick Actions', 'Recent Activity'],
footer: 'Admin System v2.1',
}
console.log('Dashboard layout:', Object.keys(layout))
return { ...layout, content: 'Dashboard Statistics' }
}
function AdminUsers() {
const layout = {
header: 'Admin Panel', // Duplicated
navigation: ['Dashboard', 'Users', 'Analytics'], // Duplicated
sidebar: ['Quick Actions', 'Recent Activity'], // Duplicated
footer: 'Admin System v2.1', // Duplicated
}
console.log('Users layout:', Object.keys(layout))
return { ...layout, content: 'User Management' }
}
function AdminAnalytics() {
const layout = {
header: 'Admin Panel', // Duplicated again
navigation: ['Dashboard', 'Users', 'Analytics'],
sidebar: ['Quick Actions', 'Recent Activity'],
footer: 'Admin System v2.1',
}
return { ...layout, content: 'Analytics Dashboard' }
}
const flatRoutes = [
{ path: '/admin/dashboard', element: AdminDashboard },
{ path: '/admin/users', element: AdminUsers },
{ path: '/admin/analytics', element: AdminAnalytics },
]
console.log('Each route duplicates layout code and structure')
✅ Nested route structure
// Nested route structure with shared layout components
const React = require('react')
const { createBrowserRouter, Outlet } = require('react-router-dom')
function AdminLayout() {
const sharedLayout = {
header: 'Admin Panel',
navigation: ['Dashboard', 'Users', 'Analytics'],
sidebar: ['Quick Actions', 'Recent Activity'],
footer: 'Admin System v2.1',
}
console.log('Shared layout initialized once')
return {
...sharedLayout,
outlet: React.createElement(Outlet), // Child routes here
}
}
const nestedRoutes = [
{
path: '/admin',
element: React.createElement(AdminLayout),
children: [
{ path: 'dashboard', element: 'Dashboard Statistics' },
{ path: 'users', element: 'User Management' },
{ path: 'analytics', element: 'Analytics Dashboard' },
{
path: 'settings',
element: 'Settings Layout',
children: [
{ path: 'general', element: 'General Settings' },
{ path: 'security', element: 'Security Settings' },
],
},
],
},
]
console.log('Layout defined once, shared across all child routes')
console.log('URL structure: /admin/dashboard, /admin/users, etc.')
console.log('Supports deep nesting: /admin/settings/general')
console.log('Child routes automatically inherit parent layout')
Technical Trivia
The GitHub Dashboard Refactor of 2020: GitHub's engineering team refactored their repository management interface from a flat route structure to nested routes. The change reduced code duplication by 60% and improved page load times by 40% through better layout sharing and data prefetching.
Why flat routes became problematic: Each repository page (settings, issues, pull requests) duplicated the same navigation and layout code. Layout changes required updating dozens of components, and the lack of hierarchy made it difficult to implement consistent data loading patterns.
Nested routes solved the architecture: The new structure used a shared repository layout with Outlet components for child routes. This enabled parallel data loading for repository metadata while child routes loaded their specific content, dramatically improving both developer experience and user performance.
Master Nested Routes: Implementation Strategy
Design your nested route structure to match your component hierarchy and URL patterns. Use Outlet components in parent layouts to define where child routes render. Consider data loading strategies - parent routes can load shared data while child routes handle specific content. Start with shallow nesting and add levels as your application structure becomes clearer.