How To Set a Default Route in React Router?

Alexey Karimov

When building a single-page application (SPA) with React, it’s common for users to enter an invalid URL or hit a route that doesn’t exist. In such cases, you don’t want them to land on a blank page or see an error. 

You want them redirected to a defined, meaningful route like /home or a 404 page. That’s when you might want to set a default route.

A default route acts as a fallback for all unmatched paths. If no defined route matches the user’s URL, React Router automatically redirects them to the path you specify. This helps maintain a clean user experience and prevents dead ends in navigation.

Setting a Default Route in React Router 

React Router v7

React Router v7 continues the Routes + Route model introduced in v6, but refines the way default routes are handled. The preferred method is using an index route inside a layout route. This setup renders a component (like Home) when the base path (/) is visited—no /home path required.

This differs from React Router v6, which often used a path=”*” fallback combined with <Navigate /> to redirect users to a default route like /home.

import { BrowserRouter, Routes, Route, Outlet } from 'react-router-dom';

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route element={<Layout />}>
          <Route index element={<Home />} />
          <Route path="about" element={<About />} />
          <Route path="*" element={<NotFound />} />
        </Route>
      </Routes>
    </BrowserRouter>
  );
}

function Layout() {
  return (
    <div>
      <h1>My App</h1>
      <Outlet />
    </div>
  );
}

function Home() {
  return <h2>This is the Home page</h2>;
}

function About() {
  return <h2>This is the About page</h2>;
}

function NotFound() {
  return <h2>404 – Page Not Found</h2>;
}

In the above example, the index route sets Home as the default page rendered when users visit /. The layout structure is maintained using <Layout>, which wraps all child routes and uses <Outlet /> to inject the matched route component.

The catch-all route (path=”*”) ensures any unmatched paths display a fallback NotFound component, giving users a clear 404 screen.

React Router v6

In React Router v6, setting a default route is done using the <Navigate /> component. It replaces the older <Redirect /> component from v5. The approach is to add a catch-all route with path=”*” at the end of your <Routes> list, which redirects users to a chosen fallback route like /home.

Here’s a basic setup:

import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
import Home from './Home';
import About from './About';
import Contact from './Contact';

function AppRoutes() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/home" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
        
        {/* Default route */}
        <Route path="*" element={<Navigate to="/home" />} />
      </Routes>
    </BrowserRouter>
  );
}

export default AppRoutes;

In the above example, <Routes> holds all the valid paths. The final <Route path=”*”> acts as a fallback and matches any unknown path. The <Navigate to=”/home” /> component then redirects the user to the /home route whenever an invalid URL is entered.

When to Use replace in <Navigate>

The <Navigate /> component also accepts a replace prop. By default, React Router adds the redirect to the browser’s history stack. On clicking the back button, you can briefly see the invalid route again.

To avoid that, you can set replace={true}. This tells React Router to replace the current entry in the history stack instead of adding a new one. Here’s an example:

<Route path="*" element={<Navigate to="/home" replace />} />

This is useful when the user lands on a bad route and you want to quietly reroute them without keeping the broken URL in history. It’s a small detail, but it improves UX by making navigation feel smoother and cleaner.

Default Route vs. Catch-All Route

These two routes are often confused. A default route is typically used when there’s no specific sub-route matched within a nested layout. It acts as a fallback inside a defined section. However, a catch-all route is more general and catches any unmatched path in the application, often used at the root level.

Example of a Default Route (nested):

<Route path="/dashboard" element={<DashboardLayout />}>
  <Route index element={<DashboardHome />} />
  <Route path="reports" element={<Reports />} />
  <Route path="settings" element={<Settings />} />
</Route>

In this example, <DashboardHome /> is rendered when users visit /dashboard with no further path. This is the default (index) route within the nested layout.

Example of Catch-All Route:

<Route path="*" element={<Navigate to="/home" />} />

This one is placed outside all nested routes and ensures any unknown URL redirects users back to a safe landing page,  typically your homepage or a 404 screen.

Wrapping Up

As a best practice, make sure you’re using the right components for the version of React Router in your project. If you’re on v6, avoid using deprecated elements like <Redirect> or <Switch> and stick to <Navigate> and <Routes>

Always define your wildcard route after all specific routes to prevent premature redirects, and don’t forget to wrap your entire route setup in <BrowserRouter>, or your routes won’t work at all.

free trial banner