How to Implement a React Router DOM Redirect in React Router v6
Use the <Navigate> component for declarative redirects in JSX or the useNavigate hook for imperative navigation in event handlers and effects.
React Router v6 fundamentally changed how developers handle navigation by removing the legacy <Redirect> component in favor of more flexible APIs. If you are upgrading an application or building a new one within the facebook/react ecosystem, understanding the correct way to trigger a react router dom redirect is essential for maintaining clean, declarative routing logic.
Why React Router v6 Removed the <Redirect> Component
The v6 architecture shifted toward a fully element-based route configuration. The old <Redirect> component relied on route rendering patterns that conflicted with the new nested route model and data APIs. Replacing it with <Navigate> and useNavigate allows the router to handle react router dom redirect logic consistently across both declarative JSX and imperative JavaScript contexts.
React Router DOM Redirect Methods in v6
Using the <Navigate> Component for Declarative Redirects
The <Navigate> component renders a redirect element that changes the current location. When used with the replace prop, it swaps the current history entry instead of pushing a new one.
import { Routes, Route, Navigate } from "react-router-dom";
function App() {
return (
<Routes>
{/* Static react router dom redirect from old path to new path */}
<Route
path="/old-path"
element={<Navigate to="/new-path" replace />}
/>
<Route path="/new-path" element={<NewPage />} />
<Route path="*" element={<NotFound />} />
</Routes>
);
}
The <Navigate> component tells the router to replace the current location with /new-path.
Using the useNavigate Hook for Imperative Redirects
For dynamic navigation based on state, authentication status, or async operations, use the useNavigate hook. It returns a function that accepts a path and optional state object.
Conditional redirect in a protected route:
import { useEffect } from "react";
import { useNavigate, Outlet } from "react-router-dom";
function RequireAuth({ isAuthenticated }) {
const navigate = useNavigate();
useEffect(() => {
if (!isAuthenticated) {
// React router dom redirect preserving original location
navigate("/login", {
replace: true,
state: { from: location }
});
}
}, [isAuthenticated, navigate]);
return isAuthenticated ? <Outlet /> : null;
}
useNavigate is called inside useEffect once the auth status is known.
Redirect after form submission:
import { useNavigate } from "react-router-dom";
function ContactForm() {
const navigate = useNavigate();
const handleSubmit = async (e) => {
e.preventDefault();
// Process form data...
// Imperative react router dom redirect on success
navigate("/thank-you", { replace: true });
};
return (
<form onSubmit={handleSubmit}>
{/* form fields */}
<button type="submit">Send</button>
</form>
);
}
The navigation is performed imperatively after the async request resolves.
When to Use Each React Router DOM Redirect Approach
Choose your navigation strategy based on the context of the redirect:
<Navigate>: Use for static route mappings, legacy URL support, or any declarative scenario where the redirect logic lives entirely in the route configuration.useNavigate: Use for conditional logic, authentication guards, async post-action navigation, or any imperative scenario requiring programmatic control.
Core React Files Supporting Navigation
While React Router is a separate package, it relies on the core facebook/react repository for hook implementation and DOM interaction. The following files provide the underlying machinery that powers useNavigate and navigation transitions:
-
packages/react/src/ReactHooks.js: Contains the core hook implementation that React Router builds upon to create theuseNavigatehook. -
packages/react-dom/src/client/ReactDOMDefaultTransitionIndicator.js: Handles navigation events at the DOM level, managing transition indicators during route changes. -
scripts/flow/environment.js: Defines the Flow type signatures for navigation functions, ensuring type safety across the navigation API.
Summary
- React Router v6 removed the
<Redirect>component; use<Navigate>oruseNavigateinstead. <Navigate>provides declarative react router dom redirect capabilities ideal for static route configurations.useNavigateoffers imperative navigation for dynamic conditions, authentication checks, and post-action redirects.- Both APIs support the
replaceoption to modify history stack behavior. - The underlying implementation relies on core React hooks and DOM packages from the
facebook/reactrepository.
Frequently Asked Questions
What happened to the <Redirect> component in React Router v6?
The <Redirect> component was removed in v6 because its implementation conflicted with the new nested route architecture and data APIs. It has been replaced by the <Navigate> component for declarative redirects and the useNavigate hook for imperative navigation, both of which integrate better with the modern React Router lifecycle.
How do I prevent users from using the back button after a redirect?
Pass replace: true as an option to your navigation function or include the replace prop on the <Navigate> component. This replaces the current history entry instead of pushing a new one, effectively removing the original URL from the browser history so the back button will skip over it.
Can I pass state through a react router dom redirect?
Yes. When using useNavigate, include a state object in the options parameter: navigate("/path", { state: { from: location } }). When using <Navigate>, pass the state via the state prop: <Navigate to="/path" state={{ from: location }} replace />. The receiving component can access this state via the useLocation hook.
Is useNavigate available in React Router v5?
No, useNavigate is exclusive to React Router v6. In v5, you would use the useHistory hook and call history.push() or history.replace() for programmatic navigation. When migrating from v5 to v6, replace all useHistory usages with useNavigate and update the method signatures accordingly.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →