On this page
React Router
React Router enables navigation between pages in a single-page application without full page reloads.
Installation
npm install react-router-dom
Basic Setup
// main.jsx
import { BrowserRouter } from 'react-router-dom';
ReactDOM.createRoot(document.getElementById('root')).render(
<BrowserRouter>
<App />
</BrowserRouter>
);
// App.jsx
import { Routes, Route, Link } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';
import NotFound from './pages/NotFound';
function App() {
return (
<>
<nav>
<Link to="/">Home</Link>
<Link to="/about">About</Link>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="*" element={<NotFound />} />
</Routes>
</>
);
}
Route Parameters
// Route
<Route path="/users/:id" element={<UserProfile />} />
// Component
import { useParams } from 'react-router-dom';
function UserProfile() {
const { id } = useParams();
const [user, setUser] = useState(null);
useEffect(() => {
fetch(`/api/users/${id}`).then(r => r.json()).then(setUser);
}, [id]);
return user ? <h1>{user.name}</h1> : <p>Loading...</p>;
}
Navigation
import { Link, NavLink, useNavigate } from 'react-router-dom';
// Link
<Link to="/dashboard">Dashboard</Link>
// NavLink — active class
<NavLink to="/" className={({ isActive }) => isActive ? 'active' : ''}>
Home
</NavLink>
// Programmatic navigation
function LoginForm() {
const navigate = useNavigate();
const handleLogin = async () => {
await login();
navigate('/dashboard');
// navigate(-1) — go back
// navigate('/users', { replace: true })
};
}
Nested Routes
// App.jsx
<Route path="/dashboard" element={<DashboardLayout />}>
<Route index element={<Overview />} />
<Route path="settings" element={<Settings />} />
<Route path="profile" element={<Profile />} />
</Route>
// DashboardLayout.jsx
import { Outlet } from 'react-router-dom';
function DashboardLayout() {
return (
<div>
<Sidebar />
<main><Outlet /></main> {/* Child routes render here */}
</div>
);
}
Query Parameters
import { useSearchParams } from 'react-router-dom';
function SearchPage() {
const [searchParams, setSearchParams] = useSearchParams();
const query = searchParams.get('q') || '';
return (
<input
value={query}
onChange={e => setSearchParams({ q: e.target.value })}
/>
);
}
Protected Routes
function ProtectedRoute({ children }) {
const { user } = useAuth();
if (!user) return <Navigate to="/login" replace />;
return children;
}
<Route path="/dashboard" element={
<ProtectedRoute><Dashboard /></ProtectedRoute>
} />
Lazy Loading Routes
import { lazy, Suspense } from 'react';
const Admin = lazy(() => import('./pages/Admin'));
<Route path="/admin" element={
<Suspense fallback={<p>Loading...</p>}>
<Admin />
</Suspense>
} />
React Router is the standard routing solution for React SPAs — pair it with data fetching libraries for full-featured apps.