Fix 'No routes matched location' Error in React Router

beginnerโš›๏ธ React2026-03-25| React 18+, React Router v6 (react-router-dom 6.x), Node.js 18+, any OS

Error Message

No routes matched location "/dashboard"
#react#react-router#routing#spa

The situation

You navigate to /dashboard โ€” or click a <Link> pointing there โ€” and the screen goes blank. No component, no error boundary, just nothing. The console says:

No routes matched location "/dashboard"

React Router v6 scanned every <Route> in your <Routes> block and came up empty. There are five usual suspects. Let's rule them out one by one.

Debug process

1. Check what your route tree actually looks like

Pull up the component where you define routes and read the paths character by character. A single capital letter breaks everything:

// Wrong โ€” path says "Dashboard" (capital D)
<Route path="/Dashboard" element={<Dashboard />} />

// The Link goes to lowercase
<Link to="/dashboard">Go</Link>

React Router paths are case-sensitive. /Dashboard and /dashboard are two completely different routes โ€” it won't try to be clever about matching them.

2. Confirm the route is inside

A <Route> placed outside a <Routes> component is silently ignored. It doesn't throw, it just does nothing:

// Wrong โ€” Route is outside Routes
<BrowserRouter>
  <Route path="/dashboard" element={<Dashboard />} />
</BrowserRouter>

// Correct
<BrowserRouter>
  <Routes>
    <Route path="/dashboard" element={<Dashboard />} />
  </Routes>
</BrowserRouter>

3. Check nested route paths

In React Router v6, child paths are relative. Don't prefix them with / or repeat the parent segment:

// Wrong โ€” child path starts with /
<Route path="/app" element={<AppLayout />}>
  <Route path="/app/dashboard" element={<Dashboard />} />
</Route>

// Correct โ€” child path is relative
<Route path="/app" element={<AppLayout />}>
  <Route path="dashboard" element={<Dashboard />} />
</Route>

Writing path="/app/dashboard" on a child route tells React Router to treat it as an absolute path anchored at root โ€” not relative to the parent. Use just dashboard and the full URL resolves to /app/dashboard automatically.

4. Verify (or equivalent) wraps the whole app

Without a router context above <Routes>, nothing works. Double-check your entry point:

// main.tsx or index.tsx
import { BrowserRouter } from 'react-router-dom';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

One trap: if you're using Remix or TanStack Router, don't add a second <BrowserRouter> on top. These frameworks provide their own router context. Two nested router contexts fight each other and produce exactly this error.

5. Watch out for conditional rendering that hides routes

This one is sneaky. The route definition lives inside a condition that's false on the very first render:

// Bug: routes only render after user loads
function App() {
  const { user } = useAuth();
  return (
    <Routes>
      {user && <Route path="/dashboard" element={<Dashboard />} />}
    </Routes>
  );
}

When the page loads, user is still null. The route doesn't exist yet. So hitting /dashboard immediately triggers No routes matched โ€” even if user would become truthy 50ms later. Always define the route unconditionally. Gate access inside the component or a wrapper:

function RequireAuth({ children }: { children: JSX.Element }) {
  const { user } = useAuth();
  if (!user) return <Navigate to="/login" replace />;
  return children;
}

function App() {
  return (
    <Routes>
      <Route
        path="/dashboard"
        element={
          <RequireAuth>
            <Dashboard />
          </RequireAuth>
        }
      />
      <Route path="/login" element={<Login />} />
    </Routes>
  );
}

The complete working setup

Below is a minimal, correct React Router v6 app โ€” copy this as a reference when something goes sideways:

// main.tsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import { BrowserRouter } from 'react-router-dom';
import App from './App';

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </React.StrictMode>
);

// App.tsx
import { Routes, Route, Navigate } from 'react-router-dom';
import Dashboard from './pages/Dashboard';
import Login from './pages/Login';
import Home from './pages/Home';

export default function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/dashboard" element={<Dashboard />} />
      <Route path="/login" element={<Login />} />
      {/* Catch-all โ€” shows 404 instead of blank screen */}
      <Route path="*" element={<div>404 Not Found</div>} />
    </Routes>
  );
}

That catch-all path="*" at the bottom is worth adding to every project. A blank screen gives you nothing to debug. A 404 page at least tells you the router is running and the path simply doesn't match.

Verifying the fix

  • Navigate directly to the URL in the browser (hard refresh). The correct component should render.
  • Click a <Link to="/dashboard"> โ€” the transition should happen without a full page reload.
  • Open React DevTools, find the router context, and confirm the matched route shows /dashboard.
  • Check the browser console โ€” the No routes matched warning should be gone.

One more thing: hash router vs browser router

Static deployments (no server-side routing) have a separate gotcha. Type /dashboard directly into the address bar and the browser sends that request to your server. The server only knows about index.html, so it returns a 404 before React even loads.

Two ways to handle it:

  • Tell your server to redirect all paths to index.html โ€” the right fix for Nginx, Apache, or Cloudflare Pages.
  • Switch to <HashRouter> โ€” URLs become /#/dashboard, which never leaves the client.
// Nginx config for SPA
location / {
  try_files $uri $uri/ /index.html;
}

The symptoms look identical but the causes are different. Open the Network tab. A 200 response for the HTML file plus No routes matched in the console means a routing config problem. A 404 straight from the server means a deployment config problem. That one check splits the two cases immediately.

Related Error Notes