---
name: "up:location:changed"
area: "API"
kind: "DOM event"
parent: "up.history module"
url: "https://unpoly.com/api/up:location:changed"
---
<nav aria-label="Unpoly docs">[All docs](https://unpoly.com/index.md) · [up.history module](https://unpoly.com/api/up.history.md)</nav>

# up:location:changed

This event is [emitted](https://unpoly.com/api/up.emit.md) after the browser's address bar has been updated with a new URL.

There may be several reasons why the browser location was changed:

- A fragment update changes history through [navigation](https://unpoly.com/learn/navigation-defaults.md) or rendering with `{ history: true }`.
- The user uses the back or forward buttons in their browser UI.
- Programmatic calls to functions like [`up.history.push()`](https://unpoly.com/api/up.history.push.md) or `history.pushState()`.
- The user navigates to a different `#hash` within the page.

The `up:location:changed` event is _not_ emitted when the page is loaded initially. For this, observe [`up:framework:booted`](https://unpoly.com/api/up:framework:booted.md).

<nav aria-label="Guides">

- [Learn: Updating history](https://unpoly.com/learn/updating-history.md#observing)

</nav>

<nav aria-label="Contents">

#### Contents

- [Handling the change](#handling)
- [Location changes in overlays](#overlays)
- [Event properties](#properties)

</nav>

## Handling the change {#handling}

This event cannot be prevented, but you can mutate the `event.willHandle` property to decide whether Unpoly should handle the change by restoring a location or revealing a fragment matching the location `#hash`.

## Location changes in overlays {#overlays}

Overlays can configure whether their history state is reflected in the browser's address bar.

When a [layer](https://unpoly.com/api/up.layer.md) has no [visible history](https://unpoly.com/api/up.Layer.prototype.history.md), no `up:location:changed` event will be emitted. However, an [`up:layer:location:changed`](https://unpoly.com/api/up:layer:location:changed.md) will be emitted even if the address bar did not change.

Also see [History in overlays](https://unpoly.com/learn/history-in-overlays.md).

---

## Event properties {#properties}

### Change {#properties-change}

#### event.location {#event.location}

(required)

The new URL after the change.

When this event is emitted, the [browser location](https://unpoly.com/api/up.history.location.md) has already been updated.

Type: string

#### event.previousLocation (Experimental) {#event.previousLocation}

(required)

The URL before the change.

Type: string

#### event.reason {#event.reason}

(required)

The action that caused this change in history state.

The value of this property is one of the following:

| Value | Reason |
| --- | --- |
| `'hash'` | The location was changed, but only the `#hash` changed from the [previous location](https://unpoly.com/api/up.history.previousLocation.md). |
| `'push'` | A new history entry was added via [`up.history.push()`](https://unpoly.com/api/up.history.push.md) or `history.pushState()`. |
| `'replace'` | The current history entry was replaced via [`up.history.replace()`](https://unpoly.com/api/up.history.replace.md) or `history.replaceState()`. |
| `'pop'` | The user navigated back to the current location. |

Type: string

### Handling {#properties-handling}

#### event.alreadyHandled (Experimental) {#event.alreadyHandled}

(required)

Whether Unpoly thinks this change has already been handled and requires no additional processing.

For example, updating history by [navigating](https://unpoly.com/learn/navigation-defaults.md) or calling `history.pushState()` is considered to be already handled.

Type: boolean

#### event.willHandle (Experimental) {#event.willHandle}

(required)

Whether Unpoly will handle this change.

By default Unpoly handles changes to [owned locations](https://unpoly.com/learn/restoring-history.md#handled-entries) when the change has not [already been handled](#event.alreadyHandled).

Listeners can tell Unpoly to _not_ handle a change by setting `event.willHandle = false`. You can then handle the change with your own code.

Listeners can tell Unpoly to handle a change it does not own by setting `event.willHandle = true`. Regardless of this, Unpoly will never handle a change that has [already been handled](#event.alreadyHandled).

Type: boolean

