In modern single-page applications (SPAs), routing helps control which UI to display based on the URL — without reloading the page.
React Router enables:
-
Efficient navigation
-
Dynamic rendering
-
Cleaner UX
-
Separation of concerns between components
With a well-structured routing system, your app becomes easier to scale and maintain.
Best Practices for React Routing :
These tips are based on React Router v6+, which provides a cleaner and more powerful API than older versions.
1- Use React Router v6+
Why?
React Router v6 introduced:
-
Simplified <Routes> and <Route> structure
-
Support for nested layouts
-
Automatic route matching prioritization
-
Easier to implement code splitting
Install it:
npm install react-router-dom
2- Centralize Your Routes
Why?
Separating route logic from components keeps your app clean and easy to manage.
Example: AppRoutes.jsx
import { Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
import NotFound from './pages/NotFound';
function AppRoutes() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="*" element={<NotFound />} />
</Routes>
);
}
This modular approach makes it easy to:
-
Add/remove routes
-
Configure nested routes
-
Apply route guards
3- Use Layout Components for Shared UI
Why?
You shouldn't repeat headers, footers, or sidebars on every page. Instead, use layouts with nested routes and the <Outlet /> component.
Example:
// Layout.jsx
import { Outlet } from 'react-router-dom';
export default function Layout() {
return (
<>
<Header />
<main><Outlet /></main>
<Footer />
</>
);
}
<Routes>
<Route element={<Layout />}>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
</Route>
</Routes>
4- Use Lazy Loading for Code Splitting
Why?
Improves performance by loading components only when needed.
Example:
import { lazy, Suspense } from 'react';
const Home = lazy(() => import('./pages/Home'));
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/" element={<Home />} />
</Routes>
</Suspense>
5- Implement Route Guards (Protected Routes)
Why?
To restrict access to certain pages like dashboards or admin panels.
Example :
function PrivateRoute({ children }) {
const isAuthenticated = useAuth(); // custom hook
return isAuthenticated ? children : <Navigate to="/login" />;
}
// Usage
<Route path="/dashboard" element={<PrivateRoute><Dashboard /></PrivateRoute>} />
6- Use URL Parameters and Query Strings
Use useParams() for dynamic URLs and useSearchParams() for query strings.
Example:
<Route path="/user/:id" element={<UserProfile />} />
// UserProfile.jsx
const { id } = useParams();
This allows you to:
-
Fetch specific data
-
Share links with filters (like search, pagination)
7- Handle 404s with Wildcard Route
Why?
Prevents blank pages when users navigate to an unknown route.
Example :
<Route path="*" element={<NotFound />} />
8- Don’t Overuse Nested Routes
Use them only when routes share a common layout. Over-nesting can:
-
Make code harder to read
-
Cause unexpected layout bugs
9- Use Absolute Paths When Needed
In v6+, nested routes default to relative paths. You can use absolute paths for clarity:
<Route path="/" element={<Layout />}>
<Route path="dashboard" element={<Dashboard />} /> // relative
<Route path="/settings" element={<Settings />} /> // absolute
</Route>
10- Scroll to Top on Navigation
React Router doesn’t scroll to the top automatically. Add a global scroll-to-top handler.
Example:
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
function ScrollToTop() {
const { pathname } = useLocation();
useEffect(() => {
window.scrollTo(0, 0);
}, [pathname]);
return null;
}
React Routing Use Cases :
Here’s how routing is used in real-world scenarios:
Static Pages
-
Routes like /home, /contact, /terms
-
Use flat routing structure
-
Useful for marketing or content-based sites
Authentication Pages
-
/login, /register, /forgot-password
-
Wrap protected routes in PrivateRoute
-
Use Navigate to redirect after login
Admin Dashboards
-
/dashboard, /dashboard/users, /dashboard/settings
-
Use layout with sidebar + nested routes
-
Separate user/admin routes if needed
eCommerce Product Pages
-
/products/:slug or /category/:name
-
Use useParams() to fetch product details
Multi-Step Forms
-
/checkout/step1, /checkout/step2, /checkout/confirmation
-
Use persistent layout to keep header/form state
Multi-language Sites (i18n)
-
/en/about, /fr/about
-
Dynamically load translations based on URL prefix
Common Mistakes to Avoid
- Repeating layout code in each route
- Not using lazy loading
- No wildcard route for 404s
- Over-nesting unrelated routes
- Forgetting to scroll to top on route change
Conclusion :
A smart routing strategy can:
-
Improve your app’s performance
-
Enhance user experience
-
Simplify maintenance
By mastering these React Router best practices, you’ll build apps that scale gracefully, load faster, and deliver better UX.