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:

Summary

  • React Router v6 removed the <Redirect> component; use <Navigate> or useNavigate instead.
  • <Navigate> provides declarative react router dom redirect capabilities ideal for static route configurations.
  • useNavigate offers imperative navigation for dynamic conditions, authentication checks, and post-action redirects.
  • Both APIs support the replace option to modify history stack behavior.
  • The underlying implementation relies on core React hooks and DOM packages from the facebook/react repository.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →