> ## Documentation Index
> Fetch the complete documentation index at: https://inertiajs.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Events

Inertia provides an event system that allows you to "hook into" the various lifecycle events of the library.

## Registering Listeners

To register an event listener, use the `router.on()` method.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });
  ```
</CodeGroup>

Under the hood, Inertia uses native browser events, so you can also interact with Inertia events using the typical event methods you may already be familiar with - just be sure to prepend `inertia:` to the event name.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  document.addEventListener("inertia:start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  document.addEventListener("inertia:start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  document.addEventListener("inertia:start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });
  ```
</CodeGroup>

## Removing Listeners

When you register an event listener, Inertia automatically returns a callback that can be invoked to remove the event listener.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  let removeStartEventListener = router.on("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });

  // Remove the listener...
  removeStartEventListener();
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  let removeStartEventListener = router.on("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });

  // Remove the listener...
  removeStartEventListener();
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  let removeStartEventListener = router.on("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });

  // Remove the listener...
  removeStartEventListener();
  ```
</CodeGroup>

Combined with hooks, you can automatically remove the event listener when components unmount.

<CodeGroup>
  ```vue Vue icon="vuejs" theme={null}
  <script setup>
  import { router } from '@inertiajs/vue3'
  import { onUnmounted } from 'vue'

  onUnmounted(
    router.on('start', (event) => {
      console.log(`Starting a visit to ${event.detail.visit.url}`)
    })
  )
  </script>
  ```

  ```jsx React icon="react" theme={null}
  import { useEffect } from "react";
  import { router } from "@inertiajs/react";

  useEffect(() => {
    return router.on("start", (event) => {
      console.log(`Starting a visit to ${event.detail.visit.url}`);
    });
  }, []);
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  $effect(() => {
    return router.on("start", (event) => {
      console.log(`Starting a visit to ${event.detail.visit.url}`);
    });
  });
  ```
</CodeGroup>

Alternatively, if you're using native browser events, you can remove the event listener using `removeEventListener()`.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  let startEventListener = (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  };

  document.addEventListener("inertia:start", startEventListener);

  // Remove the listener...
  document.removeEventListener("inertia:start", startEventListener);
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  let startEventListener = (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  };

  document.addEventListener("inertia:start", startEventListener);

  // Remove the listener...
  document.removeEventListener("inertia:start", startEventListener);
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  let startEventListener = (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  };

  document.addEventListener("inertia:start", startEventListener);

  // Remove the listener...
  document.removeEventListener("inertia:start", startEventListener);
  ```
</CodeGroup>

## One-time Listeners

You may register a listener that fires only once using the `router.once()` method. The listener is automatically removed after the first invocation.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.once("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.once("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.once("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });
  ```
</CodeGroup>

Like `router.on()`, this method returns a callback you may invoke to remove the listener before it fires.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  let removeStartEventListener = router.once("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });

  // Remove the listener before it fires...
  removeStartEventListener();
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  let removeStartEventListener = router.once("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });

  // Remove the listener before it fires...
  removeStartEventListener();
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  let removeStartEventListener = router.once("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });

  // Remove the listener before it fires...
  removeStartEventListener();
  ```
</CodeGroup>

## Cancelling Events

Some events, such as `before`, `networkError`, `httpException`, and `location`, support cancellation, allowing you to prevent Inertia's default behavior. Just like native events, the event will be cancelled if only one event listener calls `event.preventDefault()`.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("before", (event) => {
    if (!confirm("Are you sure you want to navigate away?")) {
      event.preventDefault();
    }
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("before", (event) => {
    if (!confirm("Are you sure you want to navigate away?")) {
      event.preventDefault();
    }
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("before", (event) => {
    if (!confirm("Are you sure you want to navigate away?")) {
      event.preventDefault();
    }
  });
  ```
</CodeGroup>

For convenience, if you register your event listener using `router.on()`, you can cancel the event by returning `false` from the listener.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("before", (event) => {
    return confirm("Are you sure you want to navigate away?");
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("before", (event) => {
    return confirm("Are you sure you want to navigate away?");
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("before", (event) => {
    return confirm("Are you sure you want to navigate away?");
  });
  ```
</CodeGroup>

Note, browsers do not allow cancelling the native `popstate` event, so preventing forward and back history visits while using Inertia.js is not possible.

## Before

The `before` event fires when a request is about to be made to the server. This is useful for intercepting visits.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("before", (event) => {
    console.log(`About to make a visit to ${event.detail.visit.url}`);
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("before", (event) => {
    console.log(`About to make a visit to ${event.detail.visit.url}`);
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("before", (event) => {
    console.log(`About to make a visit to ${event.detail.visit.url}`);
  });
  ```
</CodeGroup>

The primary purpose of this event is to allow you to prevent a visit from happening.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("before", (event) => {
    return confirm("Are you sure you want to navigate away?");
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("before", (event) => {
    return confirm("Are you sure you want to navigate away?");
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("before", (event) => {
    return confirm("Are you sure you want to navigate away?");
  });
  ```
</CodeGroup>

## Start

The `start` event fires when a request to the server has started. This is useful for displaying loading indicators.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("start", (event) => {
    console.log(`Starting a visit to ${event.detail.visit.url}`);
  });
  ```
</CodeGroup>

The `start` event is not cancelable.

## Progress

The `progress` event fires as progress increments during file uploads.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("progress", (event) => {
    this.form.progress = event.detail.progress.percentage;
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("progress", (event) => {
    this.form.progress = event.detail.progress.percentage;
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("progress", (event) => {
    this.form.progress = event.detail.progress.percentage;
  });
  ```
</CodeGroup>

The `progress` event is not cancelable.

## Success

The `success` event fires on successful page visits, unless validation errors are present. However, this does *not* include history visits.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("success", (event) => {
    console.log(`Successfully made a visit to ${event.detail.page.url}`);
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("success", (event) => {
    console.log(`Successfully made a visit to ${event.detail.page.url}`);
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("success", (event) => {
    console.log(`Successfully made a visit to ${event.detail.page.url}`);
  });
  ```
</CodeGroup>

The `success` event is not cancelable.

## Flash

The `flash` event fires when [flash data](/v3/data-props/flash-data) is received from the server. This is useful for displaying toast notifications or handling temporary data in a central location.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("flash", (event) => {
    if (event.detail.flash.toast) {
      showToast(event.detail.flash.toast);
    }
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("flash", (event) => {
    if (event.detail.flash.toast) {
      showToast(event.detail.flash.toast);
    }
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("flash", (event) => {
    if (event.detail.flash.toast) {
      showToast(event.detail.flash.toast);
    }
  });
  ```
</CodeGroup>

The `flash` event is not cancelable and fires on every response that carries flash data.

## Error

The `error` event fires when validation errors are present on "successful" page visits.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("error", (event) => {
    console.log(event.detail.errors);
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("error", (event) => {
    console.log(event.detail.errors);
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("error", (event) => {
    console.log(event.detail.errors);
  });
  ```
</CodeGroup>

The `error` event is not cancelable.

## HTTP Exception

The `httpException` event fires when a non-Inertia response is received from the server, such as an HTML or vanilla JSON response. A valid Inertia response is a response that has the `X-Inertia` header set to `true` with a `json` payload containing [the page object](/v3/core-concepts/the-protocol#the-page-object).

This event is fired for all response types, including `200`, `400`, and `500` response codes.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("httpException", (event) => {
    console.log(`An invalid Inertia response was received.`);
    console.log(event.detail.response);
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("httpException", (event) => {
    console.log(`An invalid Inertia response was received.`);
    console.log(event.detail.response);
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("httpException", (event) => {
    console.log(`An invalid Inertia response was received.`);
    console.log(event.detail.response);
  });
  ```
</CodeGroup>

You may cancel the `httpException` event to prevent Inertia from showing the non-Inertia response modal.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("httpException", (event) => {
    event.preventDefault();

    // Handle the invalid response yourself...
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("httpException", (event) => {
    event.preventDefault();

    // Handle the invalid response yourself...
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("httpException", (event) => {
    event.preventDefault();

    // Handle the invalid response yourself...
  });
  ```
</CodeGroup>

## Network Error

The `networkError` event fires on unexpected XHR errors such as network interruptions. In addition, this event fires for errors generated when resolving page components.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("networkError", (event) => {
    console.log(`An unexpected error occurred during an Inertia visit.`);
    console.log(event.detail.error);
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("networkError", (event) => {
    console.log(`An unexpected error occurred during an Inertia visit.`);
    console.log(event.detail.error);
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("networkError", (event) => {
    console.log(`An unexpected error occurred during an Inertia visit.`);
    console.log(event.detail.error);
  });
  ```
</CodeGroup>

You may cancel the `networkError` event to prevent the error from being thrown.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("networkError", (event) => {
    event.preventDefault();
    // Handle the error yourself
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("networkError", (event) => {
    event.preventDefault();
    // Handle the error yourself
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("networkError", (event) => {
    event.preventDefault();
    // Handle the error yourself
  });
  ```
</CodeGroup>

This event will *not* fire for XHR requests that receive `400` and `500` level responses or for non-Inertia responses, as these situations are handled in other ways by Inertia. Please consult the [error handling documentation](/v3/advanced/error-handling) for more information.

## Finish

The `finish` event fires after an XHR request has completed for both "successful" and "unsuccessful" responses. This event is useful for hiding loading indicators.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("finish", (event) => {
    NProgress.done();
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("finish", (event) => {
    NProgress.done();
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("finish", (event) => {
    NProgress.done();
  });
  ```
</CodeGroup>

The `finish` event is not cancelable.

## Navigate

The `navigate` event fires on successful page visits, as well as when navigating through history.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("navigate", (event) => {
    console.log(`Navigated to ${event.detail.page.url}`);
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("navigate", (event) => {
    console.log(`Navigated to ${event.detail.page.url}`);
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("navigate", (event) => {
    console.log(`Navigated to ${event.detail.page.url}`);
  });
  ```
</CodeGroup>

The `navigate` event is not cancelable.

## Location

<Badge>v3.6.0+</Badge>

The `location` event fires whenever Inertia is about to force a full-page navigation, either because the [asset version](/v3/advanced/asset-versioning) changed or because the server returned an `Inertia::location()` redirect. The event detail includes a `versionChange` boolean so you may tell an automatic asset version change apart from a manual redirect.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("location", (event) => {
    console.log(`Navigating to ${event.detail.url}`);
    console.log(`Triggered by a version change: ${event.detail.versionChange}`);
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("location", (event) => {
    console.log(`Navigating to ${event.detail.url}`);
    console.log(`Triggered by a version change: ${event.detail.versionChange}`);
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("location", (event) => {
    console.log(`Navigating to ${event.detail.url}`);
    console.log(`Triggered by a version change: ${event.detail.versionChange}`);
  });
  ```
</CodeGroup>

You may cancel the `location` event to take over the navigation yourself, for example to show a "new version available" banner instead of reloading.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("location", (event) => {
    if (event.detail.versionChange) {
      event.preventDefault();
      showBanner("A new version is available.");
    }
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("location", (event) => {
    if (event.detail.versionChange) {
      event.preventDefault();
      showBanner("A new version is available.");
    }
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("location", (event) => {
    if (event.detail.versionChange) {
      event.preventDefault();
      showBanner("A new version is available.");
    }
  });
  ```
</CodeGroup>

## Prefetching

The `prefetching` event fires when the router starts prefetching a page.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("prefetching", (event) => {
    console.log(`Prefetching ${event.detail.visit.url}`);
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("prefetching", (event) => {
    console.log(`Prefetching ${event.detail.visit.url}`);
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("prefetching", (event) => {
    console.log(`Prefetching ${event.detail.visit.url}`);
  });
  ```
</CodeGroup>

The `prefetching` event is not cancelable.

## Prefetched

The `prefetched` event fires when the router has successfully prefetched a page.

<CodeGroup>
  ```js Vue icon="vuejs" theme={null}
  import { router } from "@inertiajs/vue3";

  router.on("prefetched", (event) => {
    console.log(`Prefetched ${event.detail.visit.url}`);
  });
  ```

  ```jsx React icon="react" theme={null}
  import { router } from "@inertiajs/react";

  router.on("prefetched", (event) => {
    console.log(`Prefetched ${event.detail.visit.url}`);
  });
  ```

  ```js Svelte icon="s" theme={null}
  import { router } from "@inertiajs/svelte";

  router.on("prefetched", (event) => {
    console.log(`Prefetched ${event.detail.visit.url}`);
  });
  ```
</CodeGroup>

The `prefetched` event is not cancelable.

## Event Callbacks

In addition to the global events described throughout this page, Inertia also provides a number of [event callbacks](/v3/the-basics/manual-visits#event-callbacks) that fire when manually making Inertia visits.
