---
title: "\U0001F9EA usePreventNavigate | Qwik Labs"
description: Prevent navigation when your application has unsaved data.
contributors:
  - wmertens
updated_at: '2024-09-17T00:00:00Z'
created_at: '2024-09-17T00:00:00Z'
---

This feature is **EXPERIMENTAL**. We invite you to try it out and provide feedback via the [RFC issue](https://github.com/QwikDev/qwik-evolution/issues/15).

To use it, you must add `experimental: ['preventNavigate']` to your `qwikVite` plugin options.

# Preventing navigation

If the user can lose state by navigating away from the page, you can use `usePreventNavigate(callback)` to conditionally prevent the navigation.

The callback will be called with the URL that the user is trying to navigate to. If the callback returns `true`, the navigation will be prevented.

You can return a Promise, and qwik-city will wait until the promise resolves before navigating.

However, in some cases the browser will navigate without calling qwik-city, such as when the user reloads the tab or navigates using `<a/>` instead of `<Link />`. When this happens, the answer must be synchronous, and user interaction is not allowed.

You can tell the difference between qwik-city and browser navigation by looking at the provided URL. If the URL is `undefined`, the browser is navigating away, and you must respond synchronously.

Examples:

- using a modal library:

```tsx
export default component$(() => {
  const okToNavigate = useSignal(true);
  usePreventNavigate$((url) => {
    if (!okToNavigate.value) {
      // we we didn't get a url, the browser is navigating away
      // and we must respond synchronously without dialogs
      if (!url) return true;

      // Here we assume that the confirmDialog function shows a modal and returns a promise for the result
      return confirmDialog(
        `Do you want to lose changes and go to ${url}?`
      ).then(answer => !answer);
      // or simply using the browser confirm dialog:
      // return !confirm(`Do you want to lose changes and go to ${url}?`);
    }
  });

  return (
    <div>
      <button onClick$={() => (okToNavigate.value = !okToNavigate.value)}>
        toggle user state
      </button>
      application content
    </div>
  );
});
```

- Using a separate modal:

```tsx
export default component$(() => {
  const okToNavigate = useSignal(true);
  const navSig = useSignal<URL | number>();
  const showConfirm = useSignal(false);
  const nav = useNavigate();
  usePreventNavigate$((url) => {
    if (!okToNavigate.value) {
      if (url) {
        navSig.value = url;
        showConfirm.value = true;
      }
      return true;
    }
  });

  return (
    <div>
      <button onClick$={() => (okToNavigate.value = !okToNavigate.value)}>
        toggle user state
      </button>
      application content
      {showConfirm.value && (
        <div>
          <div>
            Do you want to lose changes and go to {String(navSig.value)}?
          </div>
          <button
            onClick$={() => {
              showConfirm.value = false;
              okToNavigate.value = true;
              nav(navSig.value!);
            }}
          >
            Yes
          </button>
          <button onClick$={() => (showConfirm.value = false)}>No</button>
        </div>
      )}
    </div>
  );
});
```
