Not handling 404 routes correctly

Loading

Proper 404 Error Handling in React Router

Handling 404 “Not Found” routes correctly is crucial for user experience and SEO. Here’s how to implement proper 404 handling in your React Router application.

The Problem: Missing 404 Handling

// ❌ Bad - no 404 handling
<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
</Routes>
// Any other path just shows a blank page

Solutions for Proper 404 Handling

1. Basic 404 Route

// ✅ Good - catch-all 404 route
<Routes>
  <Route path="/" element={<Home />} />
  <Route path="/about" element={<About />} />
  <Route path="*" element={<NotFound />} />
</Routes>

2. Nested Route 404s

// ✅ Good - nested 404 handling
<Routes>
  <Route path="/" element={<Layout />}>
    <Route index element={<Home />} />
    <Route path="products" element={<Products />}>
      <Route path=":id" element={<ProductDetail />} />
      <Route path="*" element={<ProductsNotFound />} />
    </Route>
    <Route path="*" element={<SiteWideNotFound />} />
  </Route>
</Routes>

3. With Data Routers (React Router 6.4+)

const router = createBrowserRouter([
  {
    path: "/",
    element: <Root />,
    errorElement: <ErrorPage />,
    children: [
      { index: true, element: <Home /> },
      { path: "about", element: <About /> },
      { path: "*", element: <NotFound /> }
    ]
  }
]);

function App() {
  return <RouterProvider router={router} />;
}

Advanced 404 Patterns

1. Custom 404 with Redirect

function NotFound() {
  const location = useLocation();

  useEffect(() => {
    // Log 404s to analytics
    track404(location.pathname);
  }, [location]);

  return (
    <div>
      <h1>404 - Page Not Found</h1>
      <p>No match for <code>{location.pathname}</code></p>
      <Link to="/">Return Home</Link>
    </div>
  );
}

2. Server-Side 404 Handling

// In your server configuration (e.g., Express)
app.get('*', (req, res) => {
  res.status(404).sendFile(path.join(__dirname, 'public', '404.html'));
});

// In your React app (for client-side routing)
<Route path="*" element={<NotFound />} status={404} />

3. Dynamic 404 Suggestions

function NotFound() {
  const location = useLocation();
  const [suggestions, setSuggestions] = useState([]);

  useEffect(() => {
    getSimilarPages(location.pathname).then(setSuggestions);
  }, [location]);

  return (
    <div>
      <h1>Page Not Found</h1>
      {suggestions.length > 0 && (
        <div>
          <p>Did you mean:</p>
          <ul>
            {suggestions.map(suggestion => (
              <li key={suggestion.path}>
                <Link to={suggestion.path}>{suggestion.title}</Link>
              </li>
            ))}
          </ul>
        </div>
      )}
    </div>
  );
}

Best Practices

  1. Always include a catch-all route (path="*")
  2. Set proper HTTP status codes for server-rendered apps
  3. Log 404 errors to your analytics service
  4. Provide helpful navigation back to working pages
  5. Consider SEO implications – Google prefers proper 404 responses

Common Mistakes to Avoid

  1. Redirecting all 404s to home – Bad for SEO and UX
   // ❌ Bad practice - silent redirect
   <Route path="*" element={<Navigate to="/" />} />
  1. No 404 handling at all – Blank pages confuse users
  2. Only client-side handling – Search engines need proper server responses
  3. Ignoring nested routes – Sub-sections should have their own 404s

Remember that proper 404 handling improves user experience, helps with SEO, and provides valuable analytics about broken links in your application.

Leave a Reply

Your email address will not be published. Required fields are marked *