main (6.23.1)dev
On this page


Type declaration
declare function useBlocker(
  shouldBlock: boolean | BlockerFunction
): Blocker;

type BlockerFunction = (args: {
  currentLocation: Location;
  nextLocation: Location;
  historyAction: HistoryAction;
}) => boolean;

type Blocker =
  | {
      state: "unblocked";
      reset: undefined;
      proceed: undefined;
      location: undefined;
  | {
      state: "blocked";
      reset(): void;
      proceed(): void;
      location: Location;
  | {
      state: "proceeding";
      reset: undefined;
      proceed: undefined;
      location: Location;

interface Location<State = any> extends Path {
  state: State;
  key: string;

interface Path {
  pathname: string;
  search: string;
  hash: string;

enum HistoryAction {
  Pop = "POP",
  Push = "PUSH",
  Replace = "REPLACE",

The useBlocker hook allows you to prevent the user from navigating away from the current location, and present them with a custom UI to allow them to confirm the navigation.

This only works for client-side navigations within your React Router application and will not block document requests. To prevent document navigations you will need to add your own `beforeunload` event handler. Blocking a user from navigating is a bit of an anti-pattern, so please carefully consider any usage of this hook and use it sparingly. In the de-facto use case of preventing a user navigating away from a half-filled form, you might consider persisting unsaved state to `sessionStorage` and automatically re-filling it if they return instead of blocking them from navigating away.
function ImportantForm() {
  let [value, setValue] = React.useState("");

  // Block navigating elsewhere when data has been entered into the input
  let blocker = useBlocker(
    ({ currentLocation, nextLocation }) =>
      value !== "" &&
      currentLocation.pathname !== nextLocation.pathname

  return (
    <Form method="post">
        Enter some important data:
          onChange={(e) => setValue(}
      <button type="submit">Save</button>

      {blocker.state === "blocked" ? (
          <p>Are you sure you want to leave?</p>
          <button onClick={() => blocker.proceed()}>
          <button onClick={() => blocker.reset()}>
      ) : null}

For a more complete example, please refer to the example in the repository.



The current state of the blocker

  • unblocked - the blocker is idle and has not prevented any navigation
  • blocked - the blocker has prevented a navigation
  • proceeding - the blocker is proceeding through from a blocked navigation


When in a blocked state, this represents the location to which we blocked a navigation. When in a proceeding state, this is the location being navigated to after a blocker.proceed() call.



When in a blocked state, you may call blocker.proceed() to proceed to the blocked location.


When in a blocked state, you may call blocker.reset() to return the blocker back to an unblocked state and leave the user at the current location.

Docs and examples CC 4.0