Catch-All Routes for 404 Handling in React Router

When users navigate to non-existent routes in your React application, they shouldn’t encounter a blank screen or browser error. A properly implemented React Router 404 page catch-all solution ensures users receive clear feedback and navigation options, improving both user experience and SEO performance.
This article demonstrates how to implement catch-all routes in React Router v6+ to handle unmatched URLs with custom 404 pages or redirects. You’ll learn to create NotFound components, configure wildcard routes, and choose between displaying custom error pages versus redirecting users to existing content.
Key Takeaways
- Use
path="*"
as the last route in your configuration to catch unmatched URLs - Custom 404 pages provide better user experience than generic browser errors
- The
<Navigate>
component offers an alternative redirect approach for simpler applications - Always test your 404 handling with both manual navigation and automated tests
- Brand consistency and helpful navigation options improve 404 page effectiveness
Why 404 Handling Matters for React Applications
User Experience
Custom 404 pages prevent user confusion when they encounter broken links or mistyped URLs. Instead of seeing generic browser errors, users receive branded, helpful messaging that keeps them engaged with your application.
Navigation Continuity
Well-designed 404 pages include navigation elements, search functionality, or suggested content that guide users back to relevant sections of your app. This reduces bounce rates and maintains user flow.
SEO Benefits
Search engines favor applications that handle non-existent routes gracefully. Custom 404 pages provide meaningful content for crawlers and signal proper error handling, which can positively impact your site’s search rankings.
Installing React Router
For browser-based React applications, install the react-router-dom
package:
npm install react-router-dom
Note: In React Router v7, most APIs can also be imported directly from react-router. For web apps, react-router-dom remains standard as it includes DOM‑specific bindings and maintains compatibility with existing v6 code.
Creating a Custom NotFound Component
Start by building a dedicated component for your React Router 404 page catch-all functionality:
// components/NotFound.jsx
import React from 'react'
import { Link } from 'react-router-dom'
function NotFound() {
return (
<div className="not-found-container">
<h1>404 - Page Not Found</h1>
<p>The page you're looking for doesn't exist.</p>
<div className="not-found-actions">
<Link to="/" className="home-link">
Return to Homepage
</Link>
<Link to="/contact" className="contact-link">
Contact Support
</Link>
</div>
</div>
)
}
export default NotFound
This component provides clear messaging and actionable navigation options. The Link
components from React Router ensure proper client-side navigation without full page reloads.
Configuring the Catch-All Route
Implement the wildcard route using path="*"
at the end of your route configuration:
// App.jsx
import React from 'react'
import { BrowserRouter, Routes, Route } from 'react-router-dom'
import Home from './pages/Home'
import About from './pages/About'
import Services from './pages/Services'
import NotFound from './components/NotFound'
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/services" element={<Services />} />
{/* Catch-all route for 404 handling */}
<Route path="*" element={<NotFound />} />
</Routes>
</BrowserRouter>
)
}
export default App
The path="*"
route must appear last in your route list. React Router matches routes from top to bottom, so placing the catch-all route at the end ensures it only triggers when no other routes match.
Alternative: Redirect Approach Using Navigate
Instead of displaying a custom 404 page, you can redirect users to an existing route:
import React from 'react'
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'
import Home from './pages/Home'
import About from './pages/About'
import Services from './pages/Services'
function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/services" element={<Services />} />
{/* Redirect unmatched routes to homepage */}
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</BrowserRouter>
)
}
The replace
prop prevents the invalid URL from appearing in the browser’s history, creating a cleaner navigation experience.
Testing Your 404 Implementation
Manual Testing
Navigate to non-existent routes in your development environment:
http://localhost:3000/nonexistent
http://localhost:3000/invalid/path
http://localhost:3000/typo-in-url
Verify that your NotFound component renders correctly or redirects function as expected.
Automated Testing
Create unit tests to ensure your catch-all routes work properly:
import { render, screen } from '@testing-library/react'
import { MemoryRouter } from 'react-router-dom'
import App from './App'
test('renders 404 page for invalid routes', () => {
render(
<MemoryRouter initialEntries={['/invalid-route']}>
<App />
</MemoryRouter>
)
expect(screen.getByText('404 - Page Not Found')).toBeInTheDocument()
})
Branding Your 404 Page
Design Consistency
Match your 404 page styling to your application’s design system. Use consistent colors, typography, and layout patterns to maintain brand coherence.
Helpful Content
Include elements that provide value to users:
- Search functionality
- Popular page links
- Recent blog posts or products
- Contact information
- Site navigation menu
Accessibility Considerations
Ensure your 404 page meets accessibility standards:
- Use semantic HTML elements
- Provide proper heading hierarchy
- Include alt text for images
- Ensure sufficient color contrast
When to Use Redirects vs Custom Pages
Choose Custom 404 Pages When:
- You want to maintain the invalid URL in the browser
- SEO requires proper 404 status codes
- Users need specific guidance or support options
- Your application has complex navigation structures
Choose Redirects When:
- You prefer seamless user experience over error messaging
- Your application has simple navigation
- You want to minimize bounce rates
- Invalid URLs are primarily from typos or outdated links
Conclusion
Implementing catch-all routes for 404 handling in React Router improves user experience, maintains navigation flow, and supports SEO best practices. Whether you choose custom NotFound components or redirect approaches depends on your application’s specific needs and user expectations.
The key is placing your wildcard route (path="*"
) at the end of your route configuration and providing meaningful feedback or navigation options to users who encounter unmatched routes.
FAQs
React Router matches routes from top to bottom, so placing the wildcard route earlier would intercept valid routes that appear below it, causing them never to render.
No, you can only have one catch-all route per Routes component. However, you can implement nested routing with separate catch-all routes in different route sections if needed.
Use Navigate for simple redirects when you want seamless user experience. Choose custom NotFound components when you need proper 404 status codes for SEO or want to provide specific user guidance.
In client-side React applications, you cannot directly control HTTP status codes. For proper SEO handling, consider server-side rendering solutions or ensure your server configuration returns 404 status codes for unmatched routes.
Yes, add analytics tracking to your NotFound component using useEffect to log when users encounter 404 pages, helping you identify broken links or common user navigation issues.