1. 7.2 APIs related to navigation and session history
      1. 7.2.1 The Window object
        1. 7.2.1.1 Opening and closing windows
        2. 7.2.1.2 Indexed access on the Window object
        3. 7.2.1.3 Named access on the Window object
        4. 7.2.1.4 Accessing related windows
        5. 7.2.1.5 Historical browser interface element APIs
      2. 7.2.2 The WindowProxy exotic object
      3. 7.2.3 The Location interface
      4. 7.2.4 The History interface
      5. 7.2.5 The navigation API
        1. 7.2.5.1 Introduction
        2. 7.2.5.2 The Navigation interface
        3. 7.2.5.3 Core infrastructure
        4. 7.2.5.4 The NavigationHistoryEntry interface
        5. 7.2.5.5 The history entry list
        6. 7.2.5.6 Initiating navigations
        7. 7.2.5.7 Ongoing navigation tracking
        8. 7.2.5.8 The NavigationActivation interface
        9. 7.2.5.9 The navigate event
          1. 7.2.5.9.1 The NavigateEvent interface
          2. 7.2.5.9.2 The NavigationDestination interface
      6. 7.2.6 Event interfaces
        1. 7.2.6.1 The NavigationCurrentEntryChangeEvent interface
        2. 7.2.6.2 The PopStateEvent interface
        3. 7.2.6.3 The HashChangeEvent interface
        4. 7.2.6.4 The PageSwapEvent interface
        5. 7.2.6.5 The PageRevealEvent interface
        6. 7.2.6.6 The PageTransitionEvent interface
        7. 7.2.6.7 The BeforeUnloadEvent interface
      7. 7.2.7 The NotRestoredReasons interface

7.2.1 The Window object

Window

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+
window.window
window.frames
window.self

These attributes all return window.

window.document

Returns the Document associated with window.

document.defaultView

Returns the Window associated with document, if there is one, or null otherwise.

7.2.1.1 Opening and closing windows
window = window.open([ url [, target [, features ] ] ])

Opens a window to show url (defaults to "about:blank"), and returns it. target (defaults to "_blank") gives the name of the new window. If a window already exists with that name, it is reused. The features argument can contain a set of comma-separated tokens:

"noopener"
"noreferrer"

These behave equivalently to the noopener and noreferrer link types on hyperlinks.

"popup"

Encourages user agents to provide a minimal web browser user interface for the new window. (Impacts the visible getter on all BarProp objects as well.)

globalThis.open("https://email.example/message/CAOOOkFcWW97r8yg=SsWg7GgCmp4suVX9o85y8BvNRqMjuc5PXg", undefined, "noopener,popup");
window.name [ = value ]

Returns the name of the window.

Can be set, to change the name.

window.close()

Closes the window.

window.closed

Returns true if the window has been closed, false otherwise.

window.stop()

Cancels the document load.

7.2.1.2 Indexed access on the Window object
window.length

Returns the number of document-tree child navigables.

window[index]

Returns the WindowProxy corresponding to the indicated document-tree child navigables.

7.2.1.3 Named access on the Window object
window[name]

Returns the indicated element or collection of elements.

As a general rule, relying on this will lead to brittle code. Which IDs end up mapping to this API can vary over time, as new features are added to the web platform, for example. Instead of this, use document.getElementById() or document.querySelector().

window.top

Returns the WindowProxy for the top-level traversable.

window.opener [ = value ]

Returns the WindowProxy for the opener browsing context.

Returns null if there isn't one or if it has been set to null.

Can be set to null.

window.parent

Returns the WindowProxy for the parent navigable.

window.frameElement

Returns the navigable container element.

Returns null if there isn't one, and in cross-origin situations.

7.2.1.5 Historical browser interface element APIs

For historical reasons, the Window interface had some properties that represented the visibility of certain web browser interface elements.

For privacy and interoperability reasons, those properties now return all return the same value: whether or not the window represents a popup window.

window.locationbar.visible

BarProp/visible

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera?Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android?Safari iOS1+Chrome Android?WebView Android37+Samsung Internet?Opera Android?
window.menubar.visible
window.personalbar.visible
window.scrollbars.visible
window.statusbar.visible
window.toolbar.visible

Returns true if the Window is not a popup; otherwise, returns false.

7.2.2 The WindowProxy exotic object

A WindowProxy is an exotic object that wraps a Window ordinary object, indirecting most operations through to the wrapped object. Each browsing context has an associated WindowProxy object. When the browsing context is navigated, the Window object wrapped by the browsing context's associated WindowProxy object is changed.

7.2.3 The Location interface

Document/location

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

Location

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet?Opera Android10.1+

Window/location

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

Each Window object is associated with a unique instance of a Location object, allocated when the Window object is created.

document.location [ = value ]
window.location [ = value ]

Returns a Location object with the current page's location.

Can be set, to navigate to another page.

Location objects provide a representation of the URL of their associated Document, as well as methods for navigating and reloading the associated navigable.

location.toString()
location.href

Returns the Location object's URL.

Can be set, to navigate to the given URL.

location.origin

Returns the Location object's URL's origin.

location.protocol

Returns the Location object's URL's scheme.

Can be set, to navigate to the same URL with a changed scheme.

location.host

Returns the Location object's URL's host and port (if different from the default port for the scheme).

Can be set, to navigate to the same URL with a changed host and port.

location.hostname

Returns the Location object's URL's host.

Can be set, to navigate to the same URL with a changed host.

location.port

Returns the Location object's URL's port.

Can be set, to navigate to the same URL with a changed port.

location.pathname

Returns the Location object's URL's path.

Can be set, to navigate to the same URL with a changed path.

location.search

Returns the Location object's URL's query (includes leading "?" if non-empty).

Can be set, to navigate to the same URL with a changed query (ignores leading "?").

location.hash

Returns the Location object's URL's fragment (includes leading "#" if non-empty).

Can be set, to navigate to the same URL with a changed fragment (ignores leading "#").

location.assign(url)

Navigates to the given URL.

location.replace(url)

Removes the current page from the session history and navigates to the given URL.

location.reload()

Reloads the current page.

location.ancestorOrigins

Returns a DOMStringList object listing the origins of the ancestor navigables' active documents.

7.2.4 The History interface

History

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+

Window/history

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android10.1+
history.length

Returns the number of overall session history entries for the current traversable navigable.

history.scrollRestoration

Returns the scroll restoration mode of the active session history entry.

history.scrollRestoration = value

Set the scroll restoration mode of the active session history entry to value.

history.state

Returns the classic history API state of the active session history entry, deserialized into a JavaScript value.

history.go()

Reloads the current page.

history.go(delta)

Goes back or forward the specified number of steps in the overall session history entries list for the current traversable navigable.

A zero delta will reload the current page.

If the delta is out of range, does nothing.

history.back()

Goes back one step in the overall session history entries list for the current traversable navigable.

If there is no previous page, does nothing.

history.forward()

Goes forward one step in the overall session history entries list for the current traversable navigable.

If there is no next page, does nothing.

history.pushState(data, "")

Adds a new entry into session history with its classic history API state set to a serialization of data. The active history entry's URL will be copied over and used for the new entry's URL.

(The second parameter exists for historical reasons, and cannot be omitted; passing the empty string is traditional.)

history.pushState(data, "", url)

Adds a new entry into session history with its classic history API state set to a serialization of data, and with its URL set to url.

If the current Document cannot have its URL rewritten to url, a "SecurityError" DOMException will be thrown.

(The second parameter exists for historical reasons, and cannot be omitted; passing the empty string is traditional.)

history.replaceState(data, "")

Updates the classic history API state of the active session history entry to a structured clone of data.

(The second parameter exists for historical reasons, and cannot be omitted; passing the empty string is traditional.)

history.replaceState(data, "", url)

Updates the classic history API state of the active session history entry to a structured clone of data, and its URL to url.

If the current Document cannot have its URL rewritten to url, a "SecurityError" DOMException will be thrown.

(The second parameter exists for historical reasons, and cannot be omitted; passing the empty string is traditional.)

document's URL targetURL can have its URL rewritten
https://example.com/home https://example.com/home#about
https://example.com/home https://example.com/home?page=shop
https://example.com/home https://example.com/shop
https://example.com/home https://user:pass@example.com/home
https://example.com/home http://example.com/home
file:///path/to/x file:///path/to/x#hash
file:///path/to/x file:///path/to/x?search
file:///path/to/x file:///path/to/y
about:blank about:blank#hash
about:blank about:blank?search
about:blank about:srcdoc
data:text/html,foo data:text/html,foo#hash
data:text/html,foo data:text/html,foo?search
data:text/html,foo data:text/html,bar
data:text/html,foo data:bar
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43 blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43#hash
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43 blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43?search
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43 blob:https://example.com/anything
blob:https://example.com/77becafe-657b-4fdc-8bd3-e83aaa5e8f43 blob:path

Note how only the URL of the Document matters, and not its origin. They can mismatch in cases like about:blank Documents with inherited origins, in sandboxed iframes, or when the document.domain setter has been used.

Consider a game where the user can navigate along a line, such that the user is always at some coordinate, and such that the user can bookmark the page corresponding to a particular coordinate, to return to it later.

A static page implementing the x=5 position in such a game could look like the following:

<!DOCTYPE HTML>
<!-- this is https://example.com/line?x=5 -->
<html lang="en">
<title>Line Game - 5</title>
<p>You are at coordinate 5 on the line.</p>
<p>
 <a href="?x=6">Advance to 6</a> or
 <a href="?x=4">retreat to 4</a>?
</p>

The problem with such a system is that each time the user clicks, the whole page has to be reloaded. Here instead is another way of doing it, using script:

<!DOCTYPE HTML>
<!-- this starts off as https://example.com/line?x=5 -->
<html lang="en">
<title>Line Game - 5</title>
<p>You are at coordinate <span id="coord">5</span> on the line.</p>
<p>
 <a href="?x=6" onclick="go(1); return false;">Advance to 6</a> or
 <a href="?x=4" onclick="go(-1); return false;">retreat to 4</a>?
</p>
<script>
 var currentPage = 5; // prefilled by server
 function go(d) {
   setupPage(currentPage + d);
   history.pushState(currentPage, "", '?x=' + currentPage);
 }
 onpopstate = function(event) {
   setupPage(event.state);
 }
 function setupPage(page) {
   currentPage = page;
   document.title = 'Line Game - ' + currentPage;
   document.getElementById('coord').textContent = currentPage;
   document.links[0].href = '?x=' + (currentPage+1);
   document.links[0].textContent = 'Advance to ' + (currentPage+1);
   document.links[1].href = '?x=' + (currentPage-1);
   document.links[1].textContent = 'retreat to ' + (currentPage-1);
 }
</script>

In systems without script, this still works like the previous example. However, users that do have script support can now navigate much faster, since there is no network access for the same experience. Furthermore, contrary to the experience the user would have with just a naïve script-based approach, bookmarking and navigating the session history still work.

In the example above, the data argument to the pushState() method is the same information as would be sent to the server, but in a more convenient form, so that the script doesn't have to parse the URL each time the user navigates.

Most applications want to use the same scroll restoration mode value for all of their history entries. To achieve this they can set the scrollRestoration attribute as soon as possible (e.g., in the first script element in the document's head element) to ensure that any entry added to the history session gets the desired scroll restoration mode.

<head>
  <script>
       if ('scrollRestoration' in history)
            history.scrollRestoration = 'manual';
  </script>
</head>
   

The navigation API, provided by the global navigation property, provides a modern and web application-focused way of managing navigations and history entries. It is a successor to the classic location and history APIs.

One ability the API provides is inspecting session history entries. For example, the following will display the entries' URLs in an ordered list:

const ol = document.createElement("ol");
ol.start = 0; // so that the list items' ordinal values match up with the entry indices

for (const entry of navigation.entries()) {
  const li = document.createElement("li");

  if (entry.index < navigation.currentEntry.index) {
    li.className = "backward";
  } else if (entry.index > navigation.currentEntry.index) {
    li.className = "forward";
  } else {
    li.className = "current";
  }

  li.textContent = entry.url;
  ol.append(li);
}

The navigation.entries() array contains NavigationHistoryEntry instances, which have other useful properties in addition to the url and index properties shown here. Note that the array only contains NavigationHistoryEntry objects that represent the current navigable, and thus its contents are not impacted by navigations inside navigable containers such as iframes, or by navigations of the parent navigable in cases where the navigation API is itself being used inside an iframe. Additionally, it only contains NavigationHistoryEntry objects representing same-origin session history entries, meaning that if the user has visited other origins before or after the current one, there will not be corresponding NavigationHistoryEntrys.


The navigation API can also be used to navigate, reload, or traverse through the history:

<button onclick="navigation.reload()">Reload</button>

<input type="url" id="navigationURL">
<button onclick="navigation.navigate(navigationURL.value)">Navigate</button>

<button id="backButton" onclick="navigation.back()">Back</button>
<button id="forwardButton" onclick="navigation.forward()">Forward</button>

<select id="traversalDestinations"></select>
<button id="goButton" onclick="navigation.traverseTo(traversalDestinations.value)">Traverse To</button>

<script>
backButton.disabled = !navigation.canGoBack;
forwardButton.disabled = !navigation.canGoForward;

for (const entry of navigation.entries()) {
  traversalDestinations.append(new Option(entry.url, entry.key));
}
</script>

Note that traversals are again limited to same-origin destinations, meaning that, for example, navigation.canGoBack will be false if the previous session history entry is for a page from another origin.


The most powerful part of the navigation API is the navigate event, which fires whenever almost any navigation or traversal occurs in the current navigable:

navigation.onnavigate = event => {
  console.log(event.navigationType); // "push", "replace", "reload", or "traverse"
  console.log(event.destination.url);
  console.log(event.userInitiated);
  // ... and other useful properties
};

(The event will not fire for location bar-initiated navigations, or navigations initiated from other windows, when the destination of the navigation is a new document.)

Much of the time, the event's cancelable property will be true, meaning this event can be canceled using preventDefault():

navigation.onnavigate = event => {
  if (event.cancelable && isDisallowedURL(event.destination.url)) {
    alert(`Please don't go to ${event.destination.url}!`);
    event.preventDefault();
  }
};

The cancelable property will be false for some "traverse" navigations, such as those taking place inside child navigables, those crossing to new origins, or when the user attempts to traverse again shortly after a previous call to preventDefault() prevented them from doing so.

The NavigateEvent's intercept() method allows intercepting a navigation and converting it into a same-document navigation:

navigation.addEventListener("navigate", e => {
  // Some navigations, e.g. cross-origin navigations, we cannot intercept.
  // Let the browser handle those normally.
  if (!e.canIntercept) {
    return;
  }

  // Similarly, don't intercept fragment navigations or downloads.
  if (e.hashChange || e.downloadRequest !== null) {
    return;
  }

  const url = new URL(event.destination.url);

  if (url.pathname.startsWith("/articles/")) {
    e.intercept({
      async handler() {
        // The URL has already changed, so show a placeholder while
        // fetching the new content, such as a spinner or loading page.
        renderArticlePagePlaceholder();

        // Fetch the new content and display when ready.
        const articleContent = await getArticleContent(url.pathname, { signal: e.signal });
        renderArticlePage(articleContent);
      }
    });
  }
});

Note that the handler function can return a promise to represent the asynchronous progress, and success or failure, of the navigation. While the promise is still pending, browser UI can treat the navigation as ongoing (e.g., by presenting a loading spinner). Other parts of the navigation API are also sensitive to these promises, such as the return value of navigation.navigate():

const { committed, finished } = await navigation.navigate("/articles/the-navigation-api-is-cool");

// The committed promise will fulfill once the URL has changed, which happens
// immediately (as long as the NavigateEvent wasn't canceled).
await committed;

// The finished promise will fulfill once the Promise returned by handler() has
// fulfilled, which happens once the article is downloaded and rendered. (Or,
// it will reject, if handler() fails along the way).
await finished;

The following are the event handlers (and their corresponding event handler event types) supported, as event handler IDL attributes, by all objects implementing the Navigation interface:

Event handler Event handler event type
onnavigate navigate
onnavigatesuccess navigatesuccess
onnavigateerror navigateerror
oncurrententrychange currententrychange

A key type used throughout the navigation API is the NavigationType enumeration:

This captures the main web developer-visible types of "navigations", which (as noted elsewhere) do not exactly correspond to this standard's singular navigate algorithm. The meaning of each value is the following:

"push"
Corresponds to calls to navigate where the history handling behavior ends up as "push", or to history.pushState().
"replace"
Corresponds to calls to navigate where the history handling behavior ends up as "replace", or to history.replaceState().
"reload"
Corresponds to calls to reload.
"traverse"
Corresponds to calls to traverse the history by a delta.
7.2.5.4 The NavigationHistoryEntry interface
entry.url

The URL of this navigation history entry.

This can return null if the entry corresponds to a different Document than the current one (i.e., if sameDocument is false), and that Document was fetched with a referrer policy of "no-referrer" or "origin", since that indicates the Document in question is hiding its URL even from other same-origin pages.

entry.key

A user agent-generated random UUID string representing this navigation history entry's place in the navigation history list. This value will be reused by other NavigationHistoryEntry instances that replace this one due to "replace" navigations, and will survive reloads and session restores.

This is useful for navigating back to this entry in the navigation history list, using navigation.traverseTo(key).

entry.id

A user agent-generated random UUID string representing this specific navigation history entry. This value will not be reused by other NavigationHistoryEntry instances. This value will survive reloads and session restores.

This is useful for associating data with this navigation history entry using other storage APIs.

entry.index

The index of this NavigationHistoryEntry within navigation.entries(), or −1 if the entry is not in the navigation history entry list.

entry.sameDocument

Indicates whether or not this navigation history entry is for the same Document as the current one, or not. This will be true, for example, when the entry represents a fragment navigation or single-page app navigation.

entry.getState()

Returns the deserialization of the state stored in this entry, which was added to the entry using navigation.navigate() or navigation.updateCurrentEntry(). This state survives reloads and session restores.

Note that in general, unless the state value is a primitive, entry.getState() !== entry.getState(), since a fresh deserialization is returned each time.

This state is unrelated to the classic history API's history.state.

The following are the event handlers (and their corresponding event handler event types) supported, as event handler IDL attributes, by all objects implementing the NavigationHistoryEntry interface:

Event handler Event handler event type
ondispose dispose
7.2.5.5 The history entry list
entries = navigation.entries()

Returns an array of NavigationHistoryEntry instances represent the current navigation history entry list, i.e., all session history entries for this navigable that are same origin and contiguous to the current session history entry.

navigation.currentEntry

Returns the NavigationHistoryEntry corresponding to the current session history entry.

navigation.updateCurrentEntry({ state })

Updates the navigation API state of the current session history entry, without performing a navigation like navigation.reload() would do.

This method is best used to capture updates to the page that have already happened, and need to be reflected into the navigation API state. For cases where the state update is meant to drive a page update, instead use navigation.navigate() or navigation.reload(), which will trigger a navigate event.

navigation.canGoBack

Returns true if the current current session history entry (i.e., currentEntry) is not the first one in the navigation history entry list (i.e., in entries()). This means that there is a previous session history entry for this navigable, and its document state's origin is same origin with the current Document's origin.

navigation.canGoForward

Returns true if the current current session history entry (i.e., currentEntry) is not the last one in the navigation history entry list (i.e., in entries()). This means that there is a next session history entry for this navigable, and its document state's origin is same origin with the current Document's origin.

{ committed, finished } = navigation.navigate(url)
{ committed, finished } = navigation.navigate(url, options)

Navigates the current page to the given url. options can contain the following values:

By default this will perform a full navigation (i.e., a cross-document navigation, unless the given URL differs only in a fragment from the current one). The navigateEvent.intercept() method can be used to convert it into a same-document navigation.

The returned promises will behave as follows:

In all cases, when the returned promises fulfill, it will be with the NavigationHistoryEntry that was navigated to.

{ committed, finished } = navigation.reload(options)

Reloads the current page. options can contain info and state, which behave as described above.

The default behavior of performing a from-network-or-cache reload of the current page can be overriden by the using the navigateEvent.intercept() method. Doing so will mean this call only updates state or passes along the appropriate info, plus performing whater actions the navigate event handlers see fit to carry out.

The returned promises will behave as follows:

{ committed, finished } = navigation.traverseTo(key)
{ committed, finished } = navigation.traverseTo(key, { info })

Traverses to the closest session history entry that matches the NavigationHistoryEntry with the given key. info can be set to any value; it will populate the info property of the corresponding NavigateEvent.

If a traversal to that session history entry is already in progress, then this will return the promises for that original traversal, and info will be ignored.

The returned promises will behave as follows:

{ committed, finished } = navigation.back(key)
{ committed, finished } = navigation.back(key, { info })

Traverses to the closest previous session history entry which results in this navigable traversing, i.e., which corresponds to a different NavigationHistoryEntry and thus will cause navigation.currentEntry to change. info can be set to any value; it will populate the info property of the corresponding NavigateEvent.

If a traversal to that session history entry is already in progress, then this will return the promises for that original traversal, and info will be ignored.

The returned promises behave equivalently to those returned by traverseTo().

{ committed, finished } = navigation.forward(key)
{ committed, finished } = navigation.forward(key, { info })

Traverses to the closest forward session history entry which results in this navigable traversing, i.e., which corresponds to a different NavigationHistoryEntry and thus will cause navigation.currentEntry to change. info can be set to any value; it will populate the info property of the corresponding NavigateEvent.

If a traversal to that session history entry is already in progress, then this will return the promises for that original traversal, and info will be ignored.

The returned promises behave equivalently to those returned by traverseTo().

7.2.5.7 Ongoing navigation tracking
navigation.transition

A NavigationTransition representing any ongoing navigation that hasn't yet reached the navigatesuccess or navigateerror stage, if one exists; or null, if there is no such transition ongoing.

Since navigation.currentEntry (and other properties like location.href) are updated immediately upon navigation, this navigation.transition property is useful for determining when such navigations are not yet fully settled, according to any handlers passed to navigateEvent.intercept().

navigation.transition.navigationType

One of "push", "replace", "reload", or "traverse", indicating what type of navigation this transition is for.

navigation.transition.from

The NavigationHistoryEntry from which the transition is coming. This can be useful to compare against navigation.currentEntry.

navigation.transition.finished

A promise which fulfills at the same time as the navigatesuccess fires, or rejects at the same time the navigateerror event fires.

navigation.activation

A NavigationActivation containing information about the most recent cross-document navigation, the navigation that "activated" this Document.

While navigation.currentEntry and the Document's URL can be updated regularly due to same-document navigations, navigation.activation stays constant, and its properties are only updated if the Document is reactivated from history.

navigation.activation.entry

A NavigationHistoryEntry, equivalent to the value of the navigation.currentEntry property at the moment the Document was activated.

navigation.activation.from

A NavigationHistoryEntry, representing the Document that was active right before the current Document. This will have a value null in case the previous Document was not same origin with this one or if it was the initial about:blank Document.

There are some cases in which either the from or entry NavigationHistoryEntry objects would not be viable targets for the traverseTo() method, as they might not be retained in history. For example, the Document can be activated using location.replace() or its initial entry could be replaced by history.replaceState(). However, those entries' url property and getState() method are still accessible.

navigation.activation.navigationType

One of "push", "replace", "reload", or "traverse", indicating what type of navigation activated this Document.

Each Navigation has an associated activation, which is null or a NavigationActivation object, initially null.

Each NavigationActivation has:

The activation getter steps are to return this's activation.

The from getter steps are to return this's old entry.

The entry getter steps are to return this's new entry.

The navigationType getter steps are to return this's navigation type.

7.2.5.9 The navigate event

A major feature of the navigation API is the navigate event. This event is fired on any navigation (in the broad sense of the word), allowing web developers to monitor such outgoing navigations. In many cases, the event is cancelable, which allows preventing the navigation from happening. And in others, the navigation can be intercepted and replaced with a same-document navigation by using the intercept() method of the NavigateEvent class.

7.2.5.9.1 The NavigateEvent interface
event.navigationType

One of "push", "replace", "reload", or "traverse", indicating what type of navigation this is.

event.destination

A NavigationDestination representing the destination of the navigation.

event.canIntercept

True if intercept() can be called to intercept this navigation and convert it into a same-document navigation, replacing its usual behavior; false otherwise.

Generally speaking, this will be true whenever the current Document can have its URL rewritten to the destination URL, except for in the case of cross-document "traverse" navigations, where it will always be false.

event.userInitiated

True if this navigation was due to a user clicking on an a element, submitting a form element, or using the browser UI to navigate; false otherwise.

event.hashChange

True for a fragment navigation; false otherwise.

event.signal

An AbortSignal which will become aborted if the navigation gets canceled, e.g., by the user pressing their browser's "Stop" button, or by another navigation interrupting this one.

The expected pattern is for developers to pass this along to any async operations, such as fetch(), which they perform as part of handling this navigation.

event.formData

The FormData representing the submitted form entries for this navigation, if this navigation is a "push" or "replace" navigation representing a POST form submission; null otherwise.

(Notably, this will be null even for "reload" or "traverse" navigations that are revisiting a session history entry that was originally created from a form submission.)

event.downloadRequest

Represents whether or not this navigation was requested to be a download, by using an a or area element's download attribute:

Note that a download being requested does not always mean that a download will happen: for example, a download might be blocked by browser security policies, or end up being treated as a "push" navigation for unspecified reasons.

Similarly, a navigation might end up being a download even if it was not requested to be one, due to the destination server responding with a `Content-Disposition: attachment` header.

Finally, note that the navigate event will not fire at all for downloads initiated using browser UI affordances, e.g., those created by right-clicking and choosing to save the target of a link.

event.info

An arbitrary JavaScript value passed via one of the navigation API methods which initiated this navigation, or undefined if the navigation was initiated by the user or by a different API.

event.hasUAVisualTransition

Returns true if the user agent performed a visual transition for this navigation before dispatching this event. If true, the best user experience will be given if the author synchronously updates the DOM to the post-navigation state.

event.intercept({ handler, focusReset, scroll })

Intercepts this navigation, preventing its normal handling and instead converting it into a same-document navigation of the same type to the destination URL.

The handler option can be a function that returns a promise. The handler function will run after the navigate event has finished firing, and the navigation.currentEntry property has been synchronously updated. This returned promise is used to signal the duration, and success or failure, of the navigation. After it settles, the browser signals to the user (e.g., via a loading spinner UI, or assistive technology) that the navigation is finished. Additionally, it fires navigatesuccess or navigateerror events as appropriate, which other parts of the web application can respond to.

By default, using this method will cause focus to reset when any handlers' returned promises settle. Focus will be reset to the first element with the autofocus attribute set, or the body element if the attribute isn't present. The focusReset option can be set to "manual" to avoid this behavior.

By default, using this method will delay the browser's scroll restoration logic for "traverse" or "reload" navigations, or its scroll-reset/scroll-to-a-fragment logic for "push" or "replace" navigations, until any handlers' returned promises settle. The scroll option can be set to "manual" to turn off any browser-driven scroll behavior entirely for this navigation, or scroll() can be called before the promise settles to trigger this behavior early.

This method will throw a "SecurityError" DOMException if canIntercept is false, or if isTrusted is false. It will throw an "InvalidStateError" DOMException if not called synchronously, during event dispatch.

event.scroll()

For "traverse" or "reload" navigations, restores the scroll position using the browser's usual scroll restoration logic.

For "push" or "replace" navigations, either resets the scroll position to the top of the document or scrolls to the fragment specified by destination.url if there is one.

If called more than once, or called after automatic post-transition scroll processing has happened due to the scroll option being left as "after-transition", or called before the navigation has committed, this method will throw an "InvalidStateError" DOMException.

7.2.5.9.2 The NavigationDestination interface
event.destination.url

The URL being navigated to.

event.destination.key

The value of the key property of the destination NavigationHistoryEntry, if this is a "traverse" navigation, or the empty string otherwise.

event.destination.id

The value of the id property of the destination NavigationHistoryEntry, if this is a "traverse" navigation, or the empty string otherwise.

event.destination.index

The value of the index property of the destination NavigationHistoryEntry, if this is a "traverse" navigation, or −1 otherwise.

event.destination.sameDocument

Indicates whether or not this navigation is to the same Document as the current one, or not. This will be true, for example, in the case of fragment navigations or history.pushState() navigations.

Note that this property indicates the original nature of the navigation. If a cross-document navigation is converted into a same-document navigation using navigateEvent.intercept(), that will not change the value of this property.

event.destination.getState()

For "traverse" navigations, returns the deserialization of the state stored in the destination session history entry.

For "push" or "replace" navigations, returns the deserialization of the state passed to navigation.navigate(), if the navigation was initiated by that method, or undefined it if it wasn't.

For "reload" navigations, returns the deserialization of the state passed to navigation.reload(), if the reload was initiated by that method, or undefined it if it wasn't.

The NavigateEvent interface has its own dedicated section, due to its complexity.

7.2.6.1 The NavigationCurrentEntryChangeEvent interface
event.navigationType

Returns the type of navigation which caused the current entry to change, or null if the change is due to navigation.updateCurrentEntry().

event.from

Returns the previous value of navigation.currentEntry, before the current entry changed.

If navigationType is null or "reload", then this value will be the same as navigation.currentEntry. In that case, the event signifies that the contents of the entry changed, even if we did not move to a new entry or replace the current one.

7.2.6.2 The PopStateEvent interface

PopStateEvent/PopStateEvent

Support in all current engines.

Firefox11+Safari6+Chrome16+
Opera?Edge79+
Edge (Legacy)14+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

PopStateEvent

Support in all current engines.

Firefox4+Safari6+Chrome4+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android12.1+
event.state

Returns a copy of the information that was provided to pushState() or replaceState().

event.hasUAVisualTransition

Returns true if the user agent performed a visual transition for this navigation before dispatching this event. If true, the best user experience will be given if the author synchronously updates the DOM to the post-navigation state.

7.2.6.3 The HashChangeEvent interface

HashChangeEvent/HashChangeEvent

Support in all current engines.

Firefox11+Safari6+Chrome16+
Opera?Edge79+
Edge (Legacy)12+Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

HashChangeEvent

Support in all current engines.

Firefox3.6+Safari5+Chrome8+
Opera10.6+Edge79+
Edge (Legacy)12+Internet Explorer8+
Firefox Android?Safari iOS5+Chrome Android?WebView Android?Samsung Internet?Opera Android11+
event.oldURL

Returns the URL of the session history entry that was previously current.

event.newURL

Returns the URL of the session history entry that is now current.

7.2.6.4 The PageSwapEvent interface
event.activation

A NavigationActivation object representing the destination and type of the cross-document navigation. This would be null for cross-origin navigations.

event.activation.entry

A NavigationHistoryEntry, representing the Document that is about to become active.

event.activation.from

A NavigationHistoryEntry, equivalent to the value of the navigation.currentEntry property at the moment the event is fired.

event.activation.navigationType

One of "push", "replace", "reload", or "traverse", indicating what type of navigation that is about to result in a page swap.

event.viewTransition

Returns the ViewTransition object that represents an outbound cross-document view transition, if such transition is active when the event is fired. Otherwise, returns null.

7.2.6.5 The PageRevealEvent interface
event.viewTransition

Returns the ViewTransition object that represents an inbound cross-document view transition, if such transition is active when the event is fired. Otherwise, returns null.

7.2.6.6 The PageTransitionEvent interface

PageTransitionEvent/PageTransitionEvent

Support in all current engines.

Firefox11+Safari6+Chrome16+
Opera?Edge79+
Edge (Legacy)?Internet ExplorerNo
Firefox Android?Safari iOS?Chrome Android?WebView Android?Samsung Internet?Opera Android?

PageTransitionEvent

Support in all current engines.

Firefox1.5+Safari5+Chrome4+
Opera?Edge79+
Edge (Legacy)12+Internet Explorer11
Firefox Android?Safari iOS4+Chrome Android?WebView Android37+Samsung Internet?Opera Android?
event.persisted

For the pageshow event, returns false if the page is newly being loaded (and the load event will fire). Otherwise, returns true.

For the pagehide event, returns false if the page is going away for the last time. Otherwise, returns true, meaning that the page might be reused if the user navigates back to this page (if the Document's salvageable state stays true).

Things that can cause the page to be unsalvageable include:

7.2.6.7 The BeforeUnloadEvent interface

BeforeUnloadEvent

Support in all current engines.

Firefox1.5+Safari7+Chrome30+
Opera?Edge79+
Edge (Legacy)?Internet Explorer4+
Firefox Android?Safari iOS?Chrome Android?WebView Android37+Samsung Internet3.0+Opera Android?

There are no BeforeUnloadEvent-specific initialization methods.

The BeforeUnloadEvent interface is a legacy interface which allows checking if unloading is canceled to be controlled not only by canceling the event, but by setting the returnValue attribute to a value besides the empty string. Authors should use the preventDefault() method, or other means of canceling events, instead of using returnValue.

7.2.7 The NotRestoredReasons interface

notRestoredReasonDetails.reason

Returns a string that explains the reason that prevented the document from being served from back/forward cache. See the definition of bfcache blocking details for the possible string values.

notRestoredReasons.src

Returns the src attribute of the document's node navigable's container if it is an iframe element. This can be null if not set or if it is not an iframe element.

notRestoredReasons.id

Returns the id attribute of the document's node navigable's container if it is an iframe element. This can be null if not set or if it is not an iframe element.

notRestoredReasons.name

Returns the name attribute of the document's node navigable's container if it is an iframe element. This can be null if not set or if it is not an iframe element.

notRestoredReasons.url

Returns the document's URL, or null if the document is in a cross-origin iframe. This is reported in addition to src because it is possible iframe navigated since the original src was set.

notRestoredReasons.reasons

Returns an array of NotRestoredReasonDetails for the document. This is null if the document is in a cross-origin iframe.

notRestoredReasons.children

Returns an array of NotRestoredReasons that are for the document’s children. This is null if the document is in a cross-origin iframe.

A NotRestoredReasonDetails object has a backing struct, a not restored reason details or null, initially null.

The reason getter steps are to return this's backing struct's reason.

To create a NotRestoredReasonDetails object given a not restored reason details backingStruct and a realm realm:

  1. Let notRestoredReasonDetails be a new NotRestoredReasonDetails object created in realm.

  2. Set notRestoredReasonDetails's backing struct to backingStruct.

  3. Return notRestoredReasonDetails.

A not restored reason details is a struct with the following items:

The reason is a string that represents the reason that prevented the page from being restored from back/forward cache. The string is one of the following:

"fetch"
While unloading, a fetch initiated by this Document was still ongoing and was canceled, so the page was not in a state that could be stored in the back/forward cache.
"navigation-failure"
The original navigation that created this Document errored, so storing the resulting error document in the back/forward cache was prevented.
"parser-aborted"
The Document never finished its initial HTML parsing, so storing the unfinished document in the back/forward cache was prevented.
"websocket"
While unloading, an open WebSocket connection was shut down, so the page was not in a state that could be stored in the back/forward cache. [WEBSOCKETS]
"lock"
While unloading, held locks and lock requests were terminated, so the page was not in a state that could be stored in the back/forward cache. [WEBLOCKS]
"masked"
This Document has children that are in a cross-origin iframe, and they prevented back/forward cache; or this Document could not be back/forward cached for user agent-specific reasons, and the user agent has chosen not to use one of the more specific reasons from the list of user-agent specific blocking reasons.

In addition to the list above, a user agent might choose to expose a reason that prevented the page from being restored from back/forward cache for user-agent specific blocking reasons. These are one of the following strings:

"audio-capture"
The Document requested audio capture permission by using Media Capture and Streams's getUserMedia() with audio. [MEDIASTREAM]
"background-work"
The Document requested background work by calling SyncManager's register() method, PeriodicSyncManager's register() method, or BackgroundFetchManager's fetch() method.
"broadcastchannel-message"
While the page was stored in back/forward cache, a BroadcastChannel connection on the page received a message and message event was fired.
"idbversionchangeevent"
The Document had a pending IDBVersionChangeEvent while unloading. [INDEXEDDB]
"idledetector"
The Document had an active IdleDetector while unloading.
"keyboardlock"
While unloading, keyboard lock was still active because Keyboard's lock() method was called.
"mediastream"
A MediaStreamTrack was in the live state upon unloading. [MEDIASTREAM]
"midi"
The Document requested a MIDI permission by calling navigator.requestMIDIAccess().
"modals"
User prompts were shown while unloading.
"navigating"
While unloading, loading was still ongoing, and so the Document was not in a state that could be stored in back/forward cache.
"navigation-canceled"
The navigation request was canceled by calling window.stop() and the page was not in a state to be stored in back/forward cache.
"non-trivial-browsing-context-group"
The browsing context group of this Document had more than one top-level browsing context.
"otpcredential"
The Document created an OTPCredential.
"outstanding-network-request"
While unloading, the Document had outstanding network requests and was not in a state that could be stored in back/forward cache.
"paymentrequest"
The Document had an active PaymentRequest while unloading. [PAYMENTREQUEST]
"pictureinpicturewindow"
The Document had an active PictureInPictureWindow while unloading. [PICTUREINPICTURE]
"plugins"
The Document contained plugins.
"request-method-not-get"
The Document was created from an HTTP request whose method was not `GET`. [FETCH]
"response-auth-required"
The Document was created from an HTTP response that required HTTP authentication.
"response-cache-control-no-store"
The Document was created from an HTTP response whose `Cache-Control` header included the "no-store" token. [HTTP]
"response-cache-control-no-cache"
The Document was created from an HTTP response whose `Cache-Control` header included the "no-cache" token. [HTTP]
"response-keep-alive"
The Document was created from an HTTP response that contained a `Keep-Alive` header.
"response-scheme-not-http-or-https"
The Document was created from a response whose URL's scheme was not an HTTP(S) scheme. [FETCH]
"response-status-not-ok"
The Document was created from an HTTP response whose status was not an ok status. [FETCH]
"rtc"
While unloading, a RTCPeerConnection or RTCDataChannel was shut down, so the page was not in a state that could be stored in the back/forward cache. [WEBRTC]
"sensors"
The Document requested sensor access.
"serviceworker-added"
The Document's service worker client started to be controlled by a ServiceWorker while the page was in back/forward cache. [SW]
"serviceworker-claimed"
The Document's service worker client's active service worker was claimed while the page was in back/forward cache. [SW]
"serviceworker-postmessage"
The Document's service worker client's active service worker received a message while the page was in back/forward cache. [SW]
"serviceworker-version-activated"
The Document's service worker client's active service worker's version was activated while the page was in back/forward cache. [SW]
"serviceworker-unregistered"
The Document's service worker client's active service worker's service worker registration was unregistered while the page was in back/forward cache. [SW]
"sharedworker"
This Document was in the owner set of a SharedWorkerGlobalScope.
"smartcardconnection"
The Document had an active SmartCardConnection while unloading.
"speechrecognition"
The Document had an active SpeechRecognition while unloading.
"storageaccess"
The Document requested storage access permission by using the Storage Access API.
"unload-listener"
The Document registered an event listener for the unload event.
"video-capture"
The Document requested video capture permission by using Media Capture and Streams's getUserMedia() with video. [MEDIASTREAM]
"webhid"
The Document called the WebHID API's requestDevice() method.
"webshare"
The Document used the Web Share API's navigator.share() method.
"webtransport"
While unloading, an open WebTransport connection was shut down, so the page was not in a state that could be stored in the back/forward cache. [WEBTRANSPORT]
"webxrdevice"
The Document created a XRSystem.

A NotRestoredReasons object has a backing struct, a not restored reasons or null, initially null.

A NotRestoredReasons object has a reasons array, a FrozenArray<NotRestoredReasonDetails> or null, initially null.

A NotRestoredReasons object has a children array, a FrozenArray<NotRestoredReasons> or null, initially null.

The src getter steps are to return this's backing struct's src.

The id getter steps are to return this's backing struct's id.

The name getter steps are to return this's backing struct's name.

The url getter steps are:

  1. If this's backing struct's URL is null, then return null.

  2. Return this's backing struct's URL, serialized.

The reasons getter steps are to return this's reasons array.

The children getter steps are to return this's children array.

To create a NotRestoredReasons object given a not restored reasons backingStruct and a realm realm:

  1. Let notRestoredReasons be a new NotRestoredReasons object created in realm.

  2. Set notRestoredReasons's backing struct to backingStruct.

  3. If backingStruct's reasons is null, set notRestoredReasons's reasons array to null.

  4. Otherwise:

    1. Let reasonsArray be an empty list.

    2. For each reason of backingStruct's reasons:

      1. Create a NotRestoredReasonDetails object given reason and realm, and append it to reasonsArray.

    3. Set notRestoredReasons's reasons array to the result of creating a frozen array given reasonsArray.

  5. If backingStruct's children is null, set notRestoredReasons's children array to null.

  6. Otherwise:

    1. Let childrenArray be an empty list.

    2. For each child of backingStruct's children:

      1. Create a NotRestoredReasons object given child and realm and append it to childrenArray.

    3. Set notRestoredReasons's children array to the result of creating a frozen array given childrenArray.

  7. Return notRestoredReasons.

A not restored reasons is a struct with the following items:

A Document's not restored reasons is its node navigable's active session history entry's document state's not restored reasons, if Document's node navigable is a top-level traversable; otherwise null.