About this specification

This specification is like no other — it has been processed with you, the humble web developer, in mind.

The focus of this specification is readability and ease of access. Unlike the full HTML Standard, this "developer's edition" removes information that only browser vendors need know. It is automatically produced from the full specification by our build tooling, and thus always in sync with the latest developments in HTML.

To read about its conception, construction, and future, read the original press release, and the blog post about its relaunch.

Finally, feel free to contribute on GitHub to make this edition better for everyone!

    1. 7.5 Session history and navigation
      1. 7.5.1 The session history of browsing contexts
      2. 7.5.2 The History interface
      3. 7.5.3 The Location interface

7.5 Session history and navigation

7.5.1 The session history of browsing contexts

The sequence of Documents in a browsing context is its session history. Each browsing context, including nested browsing contexts, has a distinct session history. A browsing context's session history consists of a flat list of session history entries. Each session history entry consists, at a minimum, of a URL, and each entry may in addition have serialized state, a title, a Document object, form data, a scroll restoration mode, a scroll position, a browsing context name, and other information associated with it.

Each entry, when first created, has a Document. However, when a Document is not active, it's possible for it to be discarded to free resources. The URL and other data in a session history entry is then used to bring a new Document into being to take the place of the original, in case the user agent finds itself having to reactivate that Document.

Titles associated with session history entries need not have any relation with the current title of the Document. The title of a session history entry is intended to explain the state of the document at that point, so that the user can navigate the document's history.

URLs without associated serialized state are added to the session history as the user (or script) navigates from page to page.


Each Document object in a browsing context's session history is associated with a unique History object which must all model the same underlying session history.


Serialized state is a serialization (via StructuredSerializeForStorage) of an object representing a user interface state. We sometimes informally refer to "state objects", which are the objects representing user interface state supplied by the author, or alternately the objects created by deserializing (via StructuredDeserialize) serialized state.

Pages can add serialized state to the session history. These are then deserialized and returned to the script when the user (or script) goes back in the history, thus enabling authors to use the "navigation" metaphor even in one-page applications.

Serialized state is intended to be used for two main purposes: first, storing a preparsed description of the state in the URL so that in the simple case an author doesn't have to do the parsing (though one would still need the parsing for handling URLs passed around by users, so it's only a minor optimization). Second, so that the author can store state that one wouldn't store in the URL because it only applies to the current Document instance and it would have to be reconstructed if a new Document were opened.

An example of the latter would be something like keeping track of the precise coordinate from which a pop-up div was made to animate, so that if the user goes back, it can be made to animate to the same location. Or alternatively, it could be used to keep a pointer into a cache of data that would be fetched from the server based on the information in the URL, so that when going back and forward, the information doesn't have to be fetched again.


At any point, one of the entries in the session history is the current entry. This is the entry representing the active document of the browsing context. Which entry is the current entry is changed by the algorithms defined in this specification, e.g. during session history traversal.

The current entry is usually an entry for the URL of the Document. However, it can also be one of the entries for serialized state added to the history by that document.

An entry with persisted user state is one that also has user-agent defined state. This specification does not specify what kind of state can be stored.

For example, some user agents might want to persist the scroll position, or the values of form controls.

User agents that persist the value of form controls are encouraged to also persist their directionality (the value of the element's dir attribute). This prevents values from being displayed incorrectly after a history traversal when the user had originally entered the values with an explicit, non-default directionality.

An entry's scroll restoration mode indicates whether the user agent should restore the persisted scroll position (if any) when traversing to it. The scroll restoration mode may be one of the following:

"auto"
The user agent is responsible for restoring the scroll position upon navigation.
"manual"
The page is responsible for restoring the scroll position and the user agent does not attempt to do so automatically

If unspecified, the scroll restoration mode of a new entry must be set to "auto".

Entries that contain serialized state share the same Document as the entry for the page that was active when they were added.

Contiguous entries that differ just by their URLs' fragments also share the same Document.

All entries that share the same Document (and that are therefore merely different states of one particular document) are contiguous by definition.

Each Document in a browsing context can also have a latest entry. This is the entry for that Document to which the browsing context's session history was most recently traversed. When a Document is created, it initially has no latest entry.

7.5.2 The History interface

window . history . index

Returns the index of the current entry of the joint session history within the joint session history.

window . history . length

Returns the number of entries in the joint session history.

window . history . scrollRestoration [ = value ]

Returns the scroll restoration mode of the current entry in the session history.

Can be set, to change the scroll restoration mode of the current entry in the session history.

window . history . state

Returns the current serialized state, deserialized into an object.

window . history . go( [ delta ] )

Goes back or forward the specified number of steps in the joint session history.

A zero delta will reload the current page.

If the delta is out of range, does nothing.

window . history . back()

Goes back one step in the joint session history.

If there is no previous page, does nothing.

window . history . forward()

Goes forward one step in the joint session history.

If there is no next page, does nothing.

window . history . pushState(data, title [, url ] )

Pushes the given data onto the session history, with the given title, and, if provided and not null, the given URL.

window . history . replaceState(data, title [, url ] )

Updates the current entry in the session history to have the given data, title, and, if provided and not null, URL.

The joint session history of a top-level browsing context is the union of all the session histories of all browsing contexts of all the fully active Document objects that share that top-level browsing context, with all the entries that are current entries in their respective session histories removed except for the current entry of the joint session history.

The current entry of the joint session history is the entry that most recently became a current entry in its session history.

Entries in the joint session history are ordered chronologically by the time they were added to their respective session histories. Each entry has an index; the earliest entry has index 0, and the subsequent entries are numbered with consecutively increasing integers (1, 2, 3, etc).

Since each Document in a browsing context might have a different event loop, the actual state of the joint session history can be somewhat nebulous. For example, two sibling iframe elements could both traverse from one unique origin to another at the same time, so their precise order might not be well-defined; similarly, since they might only find out about each other later, they might disagree about the length of the joint session history.

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, document.title, '?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.

Applications might not use the same title for a session history entry as the value of the document's title element at that time. For example, here is a simple page that shows a block in the title element. Clearly, when navigating backwards to a previous state the user does not go back in time, and therefore it would be inappropriate to put the time in the session history title.

<!DOCTYPE HTML>
<HTML LANG=EN>
<TITLE>Line</TITLE>
<SCRIPT>
 setInterval(function () { document.title = 'Line - ' + new Date(); }, 1000);
 var i = 1;
 function inc() {
   set(i+1);
   history.pushState(i, 'Line - ' + i);
 }
 function set(newI) {
   i = newI;
   document.forms.F.I.value = newI;
 }
</SCRIPT>
<BODY ONPOPSTATE="set(event.state)">
<FORM NAME=F>
State: <OUTPUT NAME=I>1</OUTPUT> <INPUT VALUE="Increment" TYPE=BUTTON ONCLICK="inc()">
</FORM>

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>
   

7.5.3 The Location interface

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 the active document of their Document's browsing context, and allow the current entry of the browsing context's session history to be changed, by adding or replacing entries in the history object.

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 browsing contexts, from the parent browsing context to the top-level browsing context.