useNavigate
On this page

useNavigate

Type declaration
declare function useNavigate(): NavigateFunction;

interface NavigateFunction {
  (to: To, options?: NavigateOptions): void;
  (delta: number): void;
}

interface NavigateOptions {
  replace?: boolean;
  state?: any;
  preventScrollReset?: boolean;
  relative?: RelativeRoutingType;
  unstable_flushSync?: boolean;
  unstable_viewTransition?: boolean;
}

type RelativeRoutingType = "route" | "path";

It's usually better to use redirect in loaders and actions than this hook

The useNavigate hook returns a function that lets you navigate programmatically, for example in an effect:

import { useNavigate } from "react-router-dom";

function useLogoutTimer() {
  const userIsInactive = useFakeInactiveUser();
  const navigate = useNavigate();

  useEffect(() => {
    if (userIsInactive) {
      fake.logout();
      navigate("/session-timed-out");
    }
  }, [userIsInactive]);
}

The navigate function has two signatures:

  • Either pass a To value (same type as <Link to>) with an optional second options argument (similar to the props you can pass to <Link>), or
  • Pass the delta you want to go in the history stack. For example, navigate(-1) is equivalent to hitting the back button

Please see the Splat Paths section on the useResolvedPath docs for a note on the behavior of the future.v7_relativeSplatPath future flag for relative useNavigate() behavior within splat routes

options.replace

Specifying replace: true will cause the navigation to replace the current entry in the history stack instead of adding a new one.

options.state

You may include an optional state value to store in history state, which you can then access on the destination route via useLocation. For example:

navigate("/new-route", { state: { key: "value" } });

options.preventScrollReset

When using the <ScrollRestoration> component, you can disable resetting the scroll to the top of the page via options.preventScrollReset

options.relative

By default, navigation is relative to the route hierarchy (relative: "route"), so .. will go up one Route level. Occasionally, you may find that you have matching URL patterns that do not make sense to be nested, and you'd prefer to use relative path routing. You can opt into this behavior with relative: "path":

// Contact and EditContact do not share additional UI layout
<Route path="/" element={<Layout />}>
  <Route path="contacts/:id" element={<Contact />} />
  <Route
    path="contacts/:id/edit"
    element={<EditContact />}
  />
</Route>;

function EditContact() {
  // Since Contact is not a parent of EditContact we need to go up one level
  // in the path, instead of one level in the Route hierarchy
  navigate("..", { relative: "path" });
}

Please note that relative: "path" only impacts the resolution of a relative path. It does not change the "starting" location for that relative path resolution. This resolution is always relative to the current location in the Route hierarchy (i.e., the route useNavigate is called in).

If you wish to use path-relative routing against the current URL instead of the route hierarchy, you can do that with the current location and the URL constructor (note the trailing slash behavior):

// Assume the current URL is https://remix.run/docs/en/main/start/quickstart
let location = useLocation();

// Without trailing slashes
new URL(".", window.origin + location.pathname);
// 'https://remix.run/docs/en/main/start/'
new URL("..", window.origin + location.pathname);
// 'https://remix.run/docs/en/main/'

// With trailing slashes:
new URL(".", window.origin + location.pathname + "/");
// 'https://remix.run/docs/en/main/start/quickstart/'
new URL("..", window.origin + location.pathname + "/");
// 'https://remix.run/docs/en/main/start/'

options.unstable_flushSync

The unstable_flushSync option tells React Router DOM to wrap the initial state update for this navigation in a ReactDOM.flushSync call instead of the default React.startTransition. This allows you to perform synchronous DOM actions immediately after the update is flushed to the DOM.

unstable_flushSync only works when using a data router, see Picking a Router

Please note that this API is marked unstable and may be subject to breaking changes without a major release

options.unstable_viewTransition

The unstable_viewTransition option enables a View Transition for this navigation by wrapping the final state update in document.startViewTransition(). If you need to apply specific styles for this view transition, you will also need to leverage the unstable_useViewTransitionState().

unstable_viewTransition only works when using a data router, see Picking a Router

Please note that this API is marked unstable and may be subject to breaking changes without a major release

Docs and examples CC 4.0