> ## 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

<Warning>You are viewing the documentation for Inertia.js v2. Inertia.js v3 has been released and is now the default version. Please visit the [upgrade guide](/v3/getting-started/upgrade-guide) to get started.</Warning>

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}
  import { router } from '@inertiajs/vue3'
  import { onUnmounted } from 'vue'

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

  ```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 4 icon="s" theme={null}
  import { router } from '@inertiajs/svelte'
  import { onMount } from 'svelte'

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

  ```js Svelte 5 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>

## Cancelling Events

Some events, such as `before`, `exception`, and `invalid`, 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

<Badge>v2.3.3+</Badge>

The `flash` event fires when [flash data](/v2/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. [Partial reloads](/v2/data-props/partial-reloads) will only trigger the event if the flash data has changed.

## 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.

## Invalid

The `invalid` 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](/v2/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('invalid', (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('invalid', (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('invalid', (event) => {
      console.log(`An invalid Inertia response was received.`)
      console.log(event.detail.response)
  })
  ```
</CodeGroup>

You may cancel the `invalid` 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('invalid', (event) => {
      event.preventDefault()

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

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

  router.on('invalid', (event) => {
      event.preventDefault()

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

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

  router.on('invalid', (event) => {
      event.preventDefault()

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

## Exception

The `exception` 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('exception', (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('exception', (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('exception', (event) => {
      console.log(`An unexpected error occurred during an Inertia visit.`)
      console.log(event.detail.error)
  })
  ```
</CodeGroup>

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

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

  router.on('exception', (event) => {
      event.preventDefault()
      // Handle the error yourself
  })
  ```

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

  router.on('exception', (event) => {
      event.preventDefault()
      // Handle the error yourself
  })
  ```

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

  router.on('exception', (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](/v2/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.

## 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](/v2/the-basics/manual-visits#event-callbacks) that fire when manually making Inertia visits.
