1. 7.10 Session history and navigation
      1. 7.10.1 Navigables
        1. 7.10.1.1 Navigable target names
      2. 7.10.2 Traversable navigables
      3. 7.10.3 Top-level traversables
      4. 7.10.4 The session history of browsing contexts
      5. 7.10.5 The History interface
      6. 7.10.6 Implementation notes for session history
      7. 7.10.7 The Location interface
        1. 7.10.7.1 [[GetPrototypeOf]] ( )
        2. 7.10.7.2 [[SetPrototypeOf]] ( V )
        3. 7.10.7.3 [[IsExtensible]] ( )
        4. 7.10.7.4 [[PreventExtensions]] ( )
        5. 7.10.7.5 [[GetOwnProperty]] ( P )
        6. 7.10.7.6 [[DefineOwnProperty]] ( P, Desc )
        7. 7.10.7.7 [[Get]] ( P, Receiver )
        8. 7.10.7.8 [[Set]] ( P, V, Receiver )
        9. 7.10.7.9 [[Delete]] ( P )
        10. 7.10.7.10 [[OwnPropertyKeys]] ( )

7.10 Session history and navigation

A navigable presents a Document to the user via its active session history entry. It has:

The current session history entry and the active session history entry are usually the same, but they get out of sync when:

The active document and the active session history entry's document are usually the same, but they become momentarily out of sync during a reload, where the active session history entry's document is updated before the active document.

A navigable's active browsing context is its active session history entry's browsing context. If this navigable is a traversable navigable, then its active browsing context will be a top-level browsing context.

A navigable's target name is its active session history entry's document state's navigable target name.

A navigable's active URL is its active session history entry's URL.

To get the node navigable of a node node, return the navigable whose active document is node's node document.

To get the top-level traversable of a navigable inputNavigable, run these steps:

  1. Let navigable be inputNavigable

  2. While navigable's parent is not null, set navigable to navigable's parent.

  3. Return navigable.

To get the traversable navigable of a navigable inputNavigable, run these steps:

  1. Let navigable be inputNavigable

  2. While navigable is not a traversable navigable, set navigable to navigable's parent.

  3. Return navigable.

To initialize the navigable navigable navigable, given a document state documentState, run these steps:

JAKE-TODO: need to set the step of the history item. It isn't always 0.
  1. Let entry be a new session history entry, with the following:

    URL
    document's URL
    document state
    documentState
  2. Set navigable's current session history entry to entry.

  3. Set navigable's active session history entry to entry.

  4. Set navigable's active document to entry's document.

To get ordered deep nested navigables for a Document document, run these steps:

This returns the deeply nested navigables ordered so the parent appears before nested items. Algorithms rely on this ordering.

  1. Let navigables be new list.

  2. Let navigableContainers be a list of the navigable containers within document.

  3. For each navigableContainer of navigableContainers:

    1. If navigableContainer's nested navigable is null, continue

    2. Append navigableContainer's nested navigable to navigables.

    3. Let innerNavigables be the result of getting ordered deep nested navigables for navigableContainer's nested navigable's active document.

    4. Append each item of innerNavigables to navigables.

  4. Return navigables.

To get the history entries for navigable, run these steps:

  1. Let traversable be navigable's traversable navigable.

  2. Assert: This is running within traversable's session history traversal queue.

  3. If traversable is navigable, then return traversable's session history entries.

  4. Let entryLists be the ordered set « traversable's session history entries ».

  5. For each entryList of entryLists:

    1. For each entry of entryList:

      1. For each nestedHistory of entry's document state's nested histories:

        1. If nestedHistory's id is navigable's id, then return nestedHistory's entries list.

        2. Append nestedHistory's entries list to entryLists.

A valid navigable target name is any string with at least one character that does not start with a U+005F LOW LINE character. (Names starting with an underscore are reserved for special keywords.)

A valid navigable target name or keyword is any string that is either a valid navigable target name or that is an ASCII case-insensitive match for one of: _blank, _self, _parent, or _top.

These values have different meanings based on whether the page is sandboxed or not, as summarized in the following (non-normative) table. In this table, "current" means the navigable that the link or script is in, "parent" means the parent of the navigable that the link or script is in, "top" means the top-level traversable of the navigable that the link or script is in, "new" means a new traversable navigable with a null parent (which may use an auxiliary browsing context, subject to various user preferences and user agent policies), "none" means that nothing will happen, and "maybe new" means the same as "new" if the "allow-popups" keyword is also specified on the sandbox attribute (or if the user overrode the sandboxing), and the same as "none" otherwise.

Keyword Ordinary effect Effect in an iframe with...
sandbox="" sandbox="allow-top-navigation"
none specified, for links and form submissions current current current
empty string current current current
_blank new maybe new maybe new
_self current current current
_parent if there isn't a parent current current current
_parent if parent is also top parent/top none parent/top
_parent if there is one and it's not top parent none none
_top if top is current current current current
_top if top is not current top none top
name that doesn't exist new maybe new maybe new
name that exists and is a descendant specified descendant specified descendant specified descendant
name that exists and is current current current current
name that exists and is an ancestor that is top specified ancestor none specified ancestor/top
name that exists and is an ancestor that is not top specified ancestor none none
other name that exists with common top specified none none
name that exists with different top, if familiar and one permitted sandboxed navigator specified specified specified
name that exists with different top, if familiar but not one permitted sandboxed navigator specified none none
name that exists with different top, not familiar new maybe new maybe new

Most of the restrictions on sandboxed browsing contexts are applied by other algorithms, e.g. the navigation algorithm, not the rules for choosing a browsing context given below.


The rules for choosing a navigable, given a valid navigable target name or keyword name, a navigable currentNavigable, and a boolean noopener are as follows:

JAKE-TODO: This now returns two things. Also currentNavigable used to be currentContext. Need to update callsites.

  1. Let chosen be null.

  2. Let windowType be "existing or none".

  3. Let sandboxingFlagSet be currentNavigable's active document's active sandboxing flag set.

  4. If name is the empty string or an ASCII case-insensitive match for "_self", then set chosen to currentNavigable.

  5. Otherwise, if name is an ASCII case-insensitive match for "_parent", set chosen to currentNavigable's parent, if any, and currentNavigable otherwise.

  6. Otherwise, if name is an ASCII case-insensitive match for "_top", set chosen to currentNavigable's traversable navigable.

  7. Let currentContext be currentNavigable's active browsing context.

  8. Otherwise, if name is not an ASCII case-insensitive match for "_blank", there exists a navigable whose target name is the same as name, currentContext is familiar with that navigable's active browsing context, and the user agent determines that the two browsing contexts are related enough that it is ok if they reach each other, set chosen to that navigable. If there are multiple matching navigables, the user agent should pick one in some arbitrary consistent manner, such as the most recently opened, most recently focused, or more closely related, and set chosen to it.

    This will be made more precise in issue #313.

  9. Otherwise, a new top-level traversable is being requested, and what happens depends on the user agent's configuration and abilities — it is determined by the rules given for the first applicable option from the following list:

    The user agent may inform the user that a popup has been blocked.

    If sandboxingFlagSet has the sandboxed auxiliary navigation browsing context flag set

    The user agent may report to a developer console that a popup has been blocked.

    If the user agent has been configured such that in this instance it will create a new top-level traversable
    1. Set windowType to "new and unrestricted".

    2. If currentNavigable's active document's cross-origin opener policy's value is "same-origin" or "same-origin-plus-COEP", then:

      1. Let currentDocument be currentNavigable's active document.

      2. If currentDocument's origin is not same origin with currentDocument's relevant settings object's top-level origin, then set noopener to true, name to "_blank", and windowType to "new with no opener".

        In the presence of a cross-origin opener policy, nested documents that are cross-origin with their top-level browsing context's active document always set noopener to true.

    3. Let chosen be null.

    4. Let targetName be the empty string.

    5. If name is not an ASCII case-insensitive match for "_blank", then set targetName to name.

    6. If noopener is true, then set chosen to the result of creating a new top-level traversable with null, and targetName.

    7. Otherwise:

      1. Set chosen to the result of creating a new top-level traversable with currentContext, and targetName.

      2. Let newBrowsingContext be chosen's active browsing context.

      3. If sandboxingFlagSet's sandboxed navigation browsing context flag is set, then currentContext must be set as newBrowsingContext's one permitted sandboxed navigator.

    8. Let newBrowsingContext be chosen's active browsing context.

    9. If sandboxingFlagSet's sandbox propagates to auxiliary browsing contexts flag is set, then all the flags that are set in sandboxingFlagSet must be set in newBrowsingContext's popup sandboxing flag set.

    If the newly created navigable chosen is immediately navigated, then the navigation will be done with historyHandling set to "replace".

    If the user agent has been configured such that in this instance it will choose currentContext's containing navigable

    Set chosen to currentContext's containing navigable.

    If the user agent has been configured such that in this instance it will not find a browsing context

    Do nothing.

    User agents are encouraged to provide a way for users to configure the user agent to always choose currentContext's containing navigable.

  10. Return chosen and windowType.

7.10.2 Traversable navigables

A traversable navigable is a navigable that also controls which session history entry should be the current session history entry and active session history entry for itself and its descendant navigables.

In addition to the properties of a navigable, a traversable navigable has:

To get session history entries for a navigable, navigable, run these steps:

  1. Let traversable be navigable's traversable navigable.

  2. Assert: This is running within traversable's session history traversal queue.

  3. If navigable is traversable, return traversable's session history entries.

  4. Let docStates be an empty ordered set of document states.

  5. For each entry of traversable's session history entries, append entry's document state to docStates.

  6. For each docState of docStates:

    1. For each nestedHistory of docState's nested histories:

      1. If nestedHistory's id equals navigable's id, return nestedHistory's entries.

      2. For each entry of nestedHistory's entries, append entry's document state to docStates.

  7. Assert: This step is not reached.

To clear the forward session history of a traversable navigable navigable, run these steps:

  1. Assert: This is running within navigable's session history traversal queue.

  2. Let step be the navigable's current session history step.

  3. Let entryLists be the ordered set « navigable's session history entries ».

  4. For each entryList of entryLists:

    1. Remove every session history entry from entryList that has a step greater than step.

    2. For each entry of entryList:

      1. For each nestedHistory of entry's document state's nested histories, append nestedHistory's entries list to entryLists.

To get all history steps that are part of traversable navigable traversable that are in browsing session session, run these steps:

  1. Assert: This is running within traversable's session history traversal queue.

  2. Let sessionSteps be an empty ordered set of non-negative integers.

  3. Let sessionEntries be an ordered set containing items from traversable's session history entries where the browsing context's session is session.

  4. Let entryLists be the ordered set « sessionEntries ».

  5. For each entryList of entryLists:

    1. For each entry of entryList:

      1. Append entry's step to sessionSteps.

      2. For each nestedHistory of entry's document state's nested histories, append nestedHistory's entries list to entryLists.

  6. Return sessionSteps, sorted.

To apply the history step non-negative integer step to a traversable navigable traversable with boolean checkForUserCancelation and optional browsing context initiatorToCheck (default null), run these steps:

  1. Assert: This is running within traversable's session history traversal queue.

  2. Let targetTopEntry be the item in traversable's session history entries that has the greatest step less than or equal to step.

  3. Let targetSession be targetTopEntry's browsing context's session.

    Although the targetTopEntry's browsing context may change as part of this traversal, the new browsing context will have the same session.

  4. Let sessionSteps be the result of getting all history steps within traversable that are part of targetSession.

  5. Let targetStep be the greatest item in sessionSteps that is less than or equal to step.

    This caters for situations where there's no session history entry with step step, due to the removal of a navigable.

  6. Let scriptHistoryLength be the size of sessionSteps.

  7. Let scriptHistoryIndex be the index of targetStep in sessionSteps.

  8. Let toTraverse be a new list of navigables, initially empty.

  9. Let documentsToUnload be a new list of Documents, initially empty.

  10. Let potentiallyNavigated be a new list containing traversable and each item of the result of getting ordered deep nested navigables of traversable's active document.

  11. Let needsHistoryStateUpdate be a new list containing the active document of each item in potentiallyNavigated.

  12. For each navigable of potentiallyNavigated:

    1. Let targetEntry be the item in the result of getting the history entries for navigable that has the greatest step less than or equal to step.

    2. If targetEntry is navigable's current session history entry, and targetEntry's document state's reload pending is false, then continue.

    3. If initiatorToCheck is not null, and initiatorToCheck is not allowed to navigate navigable's active browsing context, then abort these steps.

    4. Append navigable to toTraverse.

    5. If targetEntry's document isn't navigable's active document, or targetEntry's document state's reload pending is true, then:

      1. Append navigable's active document to documentsToUnload.

      2. Let nestedNavigables be the result of getting ordered deep nested navigables of navigable's active document.

      3. Append each active document of nestedNavigables to documentsToUnload.

      4. Remove each item of nestedNavigables from potentiallyNavigated.

        As such, those navigables will not be visited as part of this loop.

  13. If checkForUserCancelation is true, and the result of checking if unloading is user-cancelled for documentsToUnload is true, then abort these steps.

    Some algorithms check if unloading is user-cancelled as a prerequisite to modifying the history tree. Those algoithms will set checkForUserCancelation to false when calling this algorithm to avoid performing the check twice.

  14. Set traversable's current session history step to targetStep.

  15. For each document of documentsToUnload, remove document from needsHistoryStateUpdate.

  16. For each navigable of toTraverse, in parallel:

    1. Let targetEntry be the item in the result of getting the history entries for navigable that has the greatest step less than or equal to step.

    2. Set navigable's current session history entry to targetEntry.

    3. Queue a global task on the history traversal task source given navigable's active document's relevant global object to run the steps:

      1. Let displayedEntry be navigable's active session history entry.

      2. If displayedEntry is targetEntry and targetEntry's document state's reload pending is false, then abort these steps.

      3. If displayedEntry's step is "pending", then abort these steps.

        A active session history entry's step is "pending" as the result of a synchronous navigation. Synchronous navigations always queue a task on traversable's session history traversal queue to set the active session history entry's step, add the entry into the traversable's session history entries, then apply the history step. If a "pending" entry is discovered here, it's the result of a race with a synchronous navigation. Rather than potentially undo the synchronous navigation, these steps are aborted in favour of the ones queued by the synchronous navigation.

        The displayedEntry will often equal targetEntry in the call to apply the history step following a synchronous navigation. In this case the traversable's model of session history is catching up with reality; there's no navigation to perform, as it already happened synchronously.

      4. Let previousDocument be targetEntry's document.

        This will be null unless targetEntry's document state's reload pending is true.

      5. If any of the following is true:

        Then attempt to populate the history entry's document targetEntry.

      6. If targetEntry's document is previousDocument, then abort these steps.

        This happens if the response was not an error, but not displayable either.

      7. If targetEntry's document is navigable's active document, then activate history entry targetEntry for navigable.

        Otherwise, in parallel:

        1. Let completedTasks be 0.

        2. Let totalTasks be 1.

        3. Queue a global task on the history traversal task source (JAKE-TODO: or?) given navigable's active document's relevant global object to run the steps:

          1. Let unloadTimingInfo be a new document unload timing info.

          2. Unload previousDocument with unloadTimingInfo.

          3. If targetEntry's document state's navigation metadata's had cross-origin redirect is false, and targetEntry's document's origin is the same as navigable's active document's origin, then set targetEntry's document's previous document unload timing to unloadTimingInfo.

          4. Increment completedTasks.

        4. If targetEntry's document is not an error document, then:

          1. Let nestedTargetNavigables be the result of getting ordered deep nested navigables of targetEntry's document.

          2. Let docsToUpdate be a list containing targetEntry's document and the document of each nestedTargetNavigables.

          3. Increment totalTasks by the size of docsToUpdate.

          4. For each document of docsToUpdate, queue a global task on the DOM manipulation task source (JAKE-TODO: or?) given document's relevant global object to run these steps:

            1. Set document's associated History's index to scriptHistoryIndex.

            2. Set document's associated History's length to scriptHistoryLength.

            3. If document is targetEntry's document, then:

              1. For each formControl of form controls in document with an autofill field name of "off", invoke the reset algorithm for formControl.

              2. If document's current document readiness is "complete", and document's page showing flag is true, then:

                1. Set document's page showing flag to true.

                2. Run any session history document visibility change steps for document that are defined by other applicable specifications.

                  This is specifically intended for use by Page Visibility. [PAGEVIS]

                3. Fire an event named pageshow at document's relevant global object, using PageTransitionEvent, with the persisted attribute initialized to true, and legacy target override flag set.

            4. Increment completedTasks.

        5. Wait for completedTasks to equal totalTasks.

        6. Queue a global task on the history traversal task source (JAKE-TODO: or?) given navigable's active document's relevant global object to activate history entry targetEntry for navigable.

  17. For each document of needsHistoryStateUpdate, queue a global task on the DOM manipulation task source (JAKE-TODO: or?) given document's relevant global object to run these steps:

    1. Set document's associated History's index to scriptHistoryIndex.

    2. Set document's associated History's length to scriptHistoryLength.

To activate history entry session history entry entry for navigable navigable, run these steps:

  1. Save persisted state to the navigable's active session history entry.

  2. Let newDocument be entry's document.

  3. Let documentChange be true if navigable's active document is not newDocument, otherwise false.

  4. Set navigable's active session history entry to entry.

  5. Set navigable's active document to newDocument.

  6. If newDocument is an error document, then return.

  7. If documentChange is true, queue a global task on the DOM manipulation task source given newDocument's relevant global object to run these steps, otherwise run these steps immediately:

    1. If document's latest entry is not entry, then:

      1. Let targetRealm be document's relevant Realm.

      2. Let state be null.

      3. If entry's serialized state is not null, then set state to StructuredDeserialize(entry's serialized state, targetRealm). If this throws an exception, catch it and ignore the exception.

      4. Set document's History object's state to state.

      5. If document's latest entry is not null, then fire an event named popstate at newDocument's relevant global object, using PopStateEvent, with the state attribute initialized to state.

7.10.3 Top-level traversables

A top-level traversable is a traversable navigable with a null parent.

A user agent may contain multiple top-level traversables, typically in the form of browser windows or browser tabs.

To create a new top-level traversable given an optional null or a navigable opener (default null), and an optional string targetName (default the empty string), run these steps:

  1. Let browsingContext and document be null.

  2. If opener is null, then let browsingSession and document be the result of creating a new top-level browsing context and document.

  3. Otherwise:

    1. Let openerTopLevelBrowsingContext be opener's top-level traversable's active browsing context.

    2. Let group be openerTopLevelBrowsingContext's group.

    3. Assert: group is non-null, as navigating invokes this directly.

    4. Set browsingContext and document be the result of creating a new browsing context and document with opener's active document, null, and group.

    5. Append browsingContext to group.

    6. Set browsingContext's opener browsing context to opener.

    7. Set browsingContext's virtual browsing context group ID to openerTopLevelBrowsingContext's virtual browsing context group ID.

    8. Set browsingContext's opener origin at creation to opener's active document's origin.

    9. Legacy-clone a browsing session storage shed with openerTopLevelBrowsingContext's session and browsingContext's session. [STORAGE]

    10. JAKE-TODO: Update the storage spec for the new location of session.

    In this case, browsingContext is an auxiliary browsing context.

  4. Let documentState be a new document state, with the following:

    document
    document
    browsing context
    browsingContext
    navigable target name
    targetName
  5. Let traversable be a new traversable navigable and initialize the navigable given documentState.

  6. Let initialHistoryEntry be traversable's active session history entry.

  7. Set initialHistoryEntry's step to 0.

  8. Append initialHistoryEntry to traversable's session history entries.

  9. Return traversable.

JAKE-TODO: A traversable will either contain a top-level browsing context, or an aux browsing context. This will be the only place an aux browsing context can be created.

7.10.4 The session history of browsing contexts

JAKE-TODO: rename above, rewrite below. Remove session history.

The sequence of Documents in a browsing context is its session history. Each browsing context, including child browsing contexts, has a distinct session history. A browsing context's session history consists of a flat list of session history entries.

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.

The history getter steps are to return this's associated Document's History instance.


A session history entry is a struct with the following items:

To get a session history entry's document, return its document state's document.

To get a session history entry's browsing context, return its document state's browsing context.

JAKE-TODO: Get rid of the above. BCs are not preserved for traversals https://github.com/whatwg/html/issues/5350#issuecomment-921589685. Cases that need a BC should get the document's BC (and deal with the document maybe being null).

To get a session history entry's policy container, return its document state's policy container.

JAKE-TODO: look out for things trying to set the above, and instead go via the document state.

Document state holds state about how to present and recreate a Document. It has:

An error document is a Document generated by the user agent to display an error to the user. JAKE-TODO: probably need to define this as an opaque origin or something? JAKE-TODO: Make sure this is used.

A POST resource has:

The session history entry's URL, and the document state's browsing context, nested histories, and resource are used to recreate a document state's document.

This happens when reloading a page, or when traversing to a session history entry after its document has been discarded.

In some failure cases, the document will be an error document. In this case, the Document isn't representitive of the rest of the document state. For example, the error document's browsing context may be different to the document state's browsing context.

A navigation metadata is a struct, which has the following items:

had cross-origin redirect
a boolean, initially false.

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

A scroll restoration mode indicates whether the user agent should restore the persisted scroll position (if any) when traversing to an entry. A scroll restoration mode is 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

Several contiguous entries in a session history can share the same document state. This can occur when the initial entry is reached via normal navigation, and the following entry is added via history.pushState(). Or it can occur via navigation to a fragment.

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

User agents may discard the documents of entries with non-null documents, as long as the following conditions are met:

Apart from these restrictions, this standard does not specify when user agents should discard an entry's document, versus keeping it cached.


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. JAKE-TODO: Replace this with navigable definition?

The current entry is usually the initial entry created upon navigation. However, it can also be one of the contiguous entries that share the same document, as described above.

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.

A nested history has:

This will later contain ways to identify a nested navigable across reloads.


To attempt to populate the history entry's document given session history entry entry, Document sourceDocument, an optional response or null response (default: null), an optional string navigationType (default: "other"), and an optional boolean allowPOST (default: false) run these steps:

JAKE-TODO: Arguments have changed here. Fix call sites.

  1. Let documentResource be entry's document state's resource.

  2. Let sandboxFlags be the result of determining the creation sandboxing flags given entry's browsing context and entry's browsing context's container.

  3. Let sourceBrowsingContext be sourceDocument's browsing context.

  4. Let allowedToDownload be the result of running the allowed to download algorithm given the sourceBrowsingContext and entry's browsing context.

  5. Let hasTransientActivation be true if the sourceBrowsingContext's active window has transient activation; otherwise false.

  6. If response is null and documentResource is a response, then set response to documentResource.

  7. Otherwise, if response is null, documentResource is a POST resource, and allowPOST is false, then set entry's document state's document to an error document and return.

    The contents of the error document aren't defined. However, if the document is going to be used as a top-level traversable's active document, then it could suggest that reloading the document will allow the POST to replay.

  8. Otherwise, if response is null, documentResource is a POST resource, and documentResource's request body is failure, then set entry's document state's document to an error document and return.

  9. Otherwise, if response is null, and documentResource is a string, then set response to a new response whose URL list consists of about:srcdoc, header list consists of `Content-Type`/`text/html`, and body is documentResource.

  10. Otherwise, if response is null, then:

    1. Let url be entry's URL.

    2. Let referrer be entry's document state's referrer.

    3. Let isReload be entry's document state's reload pending.

    4. Let request be a new request, with the following:

      policy container
      entry's document state's policy container
      client
      sourceDocument's relevant settings object
      destination
      "document"
      credentials mode
      "include"
      use-URL-credentials flag
      Set
      redirect mode
      "manual"
      replaces client id
      sourceDocument's relevant settings object's id
      mode
      "navigate"
    5. If documentResource is a POST resource, then:

      1. Set request's method to `POST`.

      2. Set request's body to documentResource's request body.

      3. Set `Content-Type` to documentResource's request content-type in request's header list.

    6. If isReload is true, then set request's reload-navigation flag.

    7. Otherwise, if entry's document state's ever populated is true, then set request's history-navigation flag.

    8. If hasTransientActivation is true, then set request's user-activation to true.

    JAKE-TODO: copy from process a navigate fetch
  11. JAKE-TODO

  12. Need to unset the target name if the eventual document origin is different to the initiating origin.

  13. Need to set "ever populated".

  14. Need to set the document state's referrer to the final value if it's "client" (initial population).

  15. Need to disallow redirects to "data" urls (the current spec doesn't).

7.10.5 The History interface

History

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

Window/history

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+
enum ScrollRestoration { "auto", "manual" };

[Exposed=Window]
interface History {
  readonly attribute unsigned long length;
  attribute ScrollRestoration scrollRestoration;
  readonly attribute any state;
  undefined go(optional long delta = 0);
  undefined back();
  undefined forward();
  undefined pushState(any data, DOMString unused, optional USVString? url = null);
  undefined replaceState(any data, DOMString unused, optional USVString? url = null);
};
window.history.length

History/length

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

Returns the number of entries in the joint session history.

window.history.scrollRestoration [ = value ]

History/scrollRestoration

Support in all current engines.

Firefox46+Safari11+Chrome46+
Opera33+Edge79+
Edge (Legacy)NoInternet ExplorerNo
Firefox Android46+Safari iOS11+Chrome Android46+WebView Android46+Samsung Internet5.0+Opera Android33+

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

History/state

Support in all current engines.

Firefox4+Safari6+Chrome19+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android4+Safari iOS6+Chrome Android25+WebView Android37+Samsung Internet1.5+Opera Android12.1+

Returns the current serialized state, deserialized into an object.

window.history.go([ delta ])

History/go

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

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()

History/back

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

Goes back one step in the joint session history.

If there is no previous page, does nothing.

window.history.forward()

History/forward

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

Goes forward one step in the joint session history.

If there is no next page, does nothing.

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

History/pushState

Support in all current engines.

Firefox4+Safari5+Chrome5+
Opera11.5+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android4+Safari iOS4+Chrome Android18+WebView Android37+Samsung Internet1.0+Opera Android11.5+

Pushes the given data onto the session history, and, if provided and not null, the given URL. (The second parameter exists for historical reasons, and cannot be omitted; passing the empty string is traditional.)

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

History/replaceState

Support in all current engines.

Firefox4+Safari5+Chrome5+
Opera11.5+Edge79+
Edge (Legacy)12+Internet Explorer10+
Firefox Android4+Safari iOS4+Chrome Android18+WebView Android37+Samsung Internet1.0+Opera Android11.5+

Updates the current entry in the session history to have the given data, and if provided and not null, URL. (The second parameter exists for historical reasons, and cannot be omitted; passing the empty string is traditional.)

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. JAKE-TODO: Get rid of this.

The current entry of the joint session history is the entry that most recently became a current entry in its session history. JAKE-TODO: Get rid of this.

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. JAKE-TODO: Get rid of this.

Each History object has state, initially null.

Each History object has a length, a non-negative integer, initially 0.

Each History object has an index, a non-negative integer, initially 0.

Although the index is not directly exposed, it can be inferred from changes to the length during synchronous navigations. In fact, that is what it's used for.

The length getter steps are:

  1. If this's associated Document is not fully active, then throw a "SecurityError" DOMException.

  2. Return this's length.

The actual entries are not accessible from script.

The scrollRestoration getter steps are:

  1. If this's associated Document is not fully active, then throw a "SecurityError" DOMException.

  2. Return this's session history's current entry's scroll restoration mode.

The scrollRestoration setter steps are:

  1. If this's associated Document is not fully active, then throw a "SecurityError" DOMException.

  2. Set this's session history's current entry's scroll restoration mode to the given value.

The state getter steps are:

  1. If this's associated Document is not fully active, then throw a "SecurityError" DOMException.

  2. Return this's state.

The go(delta) method steps are:

  1. Let document be this's associated Document.

  2. If document is not fully active, then throw a "SecurityError" DOMException.

  3. If delta is 0, then act as if the location.reload() method was called, and return.

  4. Traverse the history by a delta with delta and document's browsing context.

The back() method steps are:

  1. Let document be this's associated Document.

  2. If document is not fully active, then throw a "SecurityError" DOMException.

  3. Traverse the history by a delta with −1 and document's browsing context.

The forward() method steps are:

  1. Let document be this's associated Document.

  2. If document is not fully active, then throw a "SecurityError" DOMException.

  3. Traverse the history by a delta with +1 and document's browsing context.


Each top-level browsing context has a session history traversal queue, initially empty, to which tasks can be added.

JAKE-TODO: Remove the above and related content below. Should use tn-session-history-traversal-queue instead.

Each top-level browsing context, when created, must begin running the following algorithm, known as the session history event loop for that top-level browsing context, in parallel:

  1. Wait until this top-level browsing context's session history traversal queue is not empty.

  2. Pull the first task from this top-level browsing context's session history traversal queue, and execute it.

  3. Return to the first step of this algorithm.

The session history event loop helps coordinate cross-browsing-context transitions of the joint session history: since each browsing context might, at any particular time, have a different event loop (this can happen if the user navigates from example.com to shop.example), transitions would otherwise have to involve cross-event-loop synchronization.


To traverse the history by a delta given delta and browsing context source browsing context, the user agent must append a task to this top-level browsing context's session history traversal queue, the task consisting of running the following steps:

JAKE-TODO: this needs to be rewritten to figure out the target step and run "apply the history step"
  1. If the index of the current entry of the joint session history plus delta is less than zero or greater than or equal to the number of items in the joint session history, then return.

  2. Let specified entry be the entry in the joint session history whose index is the sum of delta and the index of the current entry of the joint session history.

  3. Let specified browsing context be the browsing context of the specified entry.

  4. If source browsing context is not allowed to navigate specified browsing context, then return.

  5. If the specified browsing context's active document's unload counter is greater than 0, then return.

  6. Queue a global task on the history traversal task source given specified browsing context's active window to perform the following steps:

    1. If there is an ongoing attempt to navigate specified browsing context that has not yet matured (i.e. it has not passed the point of making its Document the active document), then cancel that attempt to navigate the browsing context.

    2. If the specified browsing context's active document is not the same Document as the Document of the specified entry, then run these substeps:

      1. Prompt to unload the active document of the specified browsing context. If the user refused to allow the document to be unloaded, then return.

      2. Unload the active document of the specified browsing context.

    3. Traverse the history of the specified browsing context to the specified entry with explicitHistoryNavigation set to true.

When the user navigates through a browsing context, e.g. using a browser's back and forward buttons, the user agent must traverse the history by a delta with a delta equivalent to the action specified by the user and the browsing context being operated on.


The URL and history update steps, given a Document document, a URL newURL, an optional serialized state-or-null serializedData (default null), and an optional boolean isPush (default false), are:

  1. Let browsingContext be document's browsing context.

  2. Let entry be null.

  3. If isPush is true, then:

    1. Remove all the entries in browsingContext's session history after the current entry. If the current entry is the last entry in the session history, then no entries are removed.

      This doesn't necessarily have to affect the user agent's user interface.

    2. Remove any tasks queued by the history traversal task source that are associated with any Document objects in the top-level browsing context's document family.

    3. Save persisted state to the current entry.

    4. Set entry to a new session history entry, with:

      JAKE-TODO: Pretty sure the above is wrong. Needs to map to the new structure of history entries.

    5. Add a entry to browsingContext'ssession history, after the current entry.

      JAKE-TODO: The above is wrong. It needs to set the displayed entry synchronously, then queue a task to update the history tree.

    6. Update the current entry to be this newly added entry.

  4. Otherwise:

    1. Set entry to browsingContext's session history's current entry.

    2. Set entry's URL to newURL.

    3. If serializedData is not null, then set entry's serialized state to serializedData.

  5. If entry's document state's resource is a POST resource, set entry's document state's resource to null.

  6. Set document's URL to newURL.

    Since this is neither a navigation of the browsing context nor a history traversal, it does not cause a hashchange event to be fired.

  7. If serializedData is not null, then:

    1. Let state be StructuredDeserialize(serializedData, document's relevant Realm). If this throws an exception, catch it, ignore the exception, and set state to null.

    2. Set document's History instance's state to state.

  8. Set the current entry's document's latest entry to the current entry.

The pushState(data, unused, url) method steps are to run the shared history push/replace state steps given this, data, url, and true.

The replaceState(data, unused, url) method steps are to run the shared history push/replace state steps given this, data, url, and false.

The shared history push/replace state steps, given a History history, a value data, a scalar value string-or-null url, and a boolean isPush, are:

  1. Let document be history's associated Document.

  2. If document is not fully active, then throw a "SecurityError" DOMException.

  3. Optionally, return. (For example, the user agent might disallow calls to these methods that are invoked on a timer, or from event listeners that are not triggered in response to a clear user action, or that are invoked in rapid succession.)

  4. Let serializedData be StructuredSerializeForStorage(data). Rethrow any exceptions.

  5. Let newURL be the session history's current entry's URL.

  6. If url is not null, then:

    1. Parse url, relative to the relevant settings object of history.

    2. If that fails, then throw a "SecurityError" DOMException.

    3. Set newURL to the resulting URL record.

    4. Compare newURL to document's URL. If any component of these two URL records differ other than the path, query, and fragment components, then throw a "SecurityError" DOMException.

    5. If the origin of newURL is not same origin with the origin of document, and either the path or query components of the two URL records compared in the previous step differ, throw a "SecurityError" DOMException. (This prevents sandboxed content from spoofing other pages on the same origin.)

  7. Run the URL and history update steps given document and newURL, with serializedData set to serializedData and isPush set to isPush.

User agents may limit the number of state objects added to the session history per page. If a page hits the implementation-defined limit, user agents must remove the entry immediately after the first entry for that Document object in the session history after having added the new entry. (Thus the state history acts as a FIFO buffer for eviction, but as a LIFO buffer for navigation.)

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.

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, "");
 }
 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.10.6 Implementation notes for session history

JAKE-TODO: review this section

This section is non-normative.

The History interface is not meant to place restrictions on how implementations represent the session history to the user.

For example, session history could be implemented in a tree-like manner, with each page having multiple "forward" pages. This specification doesn't define how the linear list of pages in the history object are derived from the actual session history as seen from the user's perspective.

Similarly, a page containing two iframes has a history object distinct from the iframes' history objects, despite the fact that typical web browsers present the user with just one "Back" button, with a session history that interleaves the navigation of the two inner frames and the outer page.

Security: It is suggested that to avoid letting a page "hijack" the history navigation facilities of a UA by abusing pushState(), the UA provide the user with a way to jump back to the previous page (rather than just going back to the previous state). For example, the back button could have a drop down showing just the pages in the session history, and not showing any of the states. Similarly, an aural browser could have two "back" commands, one that goes back to the previous state, and one that jumps straight back to the previous page.

For both pushState() and replaceState(), user agents are encouraged to prevent abuse of these APIs via too-frequent calls or over-large state objects. As detailed above, the algorithm explicitly allows user agents to ignore any such calls when appropriate.

7.10.7 The Location interface

Document/location

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

Location

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

Window/location

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer4+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

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

The Location exotic object is defined through a mishmash of IDL, invocation of JavaScript internal methods post-creation, and overridden JavaScript internal methods. Coupled with its scary security policy, please take extra care while implementing this excrescence.

To create a Location object, run these steps:

  1. Let location be a new Location platform object.

  2. Let valueOf be location's relevant Realm.[[Intrinsics]].[[%Object.prototype.valueOf%]].

  3. Perform ! location.[[DefineOwnProperty]]("valueOf", { [[Value]]: valueOf, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }).

  4. Perform ! location.[[DefineOwnProperty]](@@toPrimitive, { [[Value]]: undefined, [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }).

  5. Set the value of the [[DefaultProperties]] internal slot of location to location.[[OwnPropertyKeys]]().

  6. Return location.

The addition of valueOf and @@toPrimitive own data properties, as well as the fact that all of Location's IDL attributes are marked [LegacyUnforgeable], is required by legacy code that consulted the Location interface, or stringified it, to determine the document URL, and then used it in a security-sensitive way. In particular, the valueOf, @@toPrimitive, and [LegacyUnforgeable] stringifier mitigations ensure that code such as foo[location] = bar or location + "" cannot be misdirected.

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

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

Can be set, to navigate to another page.

The Document object's location attribute's getter must return this Document object's relevant global object's Location object, if this Document object is fully active, and null otherwise.

The Window object's location attribute's getter must return this Window object's Location object.

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.

[Exposed=Window]
interface Location { // but see also additional creation steps and overridden internal methods
  [LegacyUnforgeable] stringifier attribute USVString href;
  [LegacyUnforgeable] readonly attribute USVString origin;
  [LegacyUnforgeable] attribute USVString protocol;
  [LegacyUnforgeable] attribute USVString host;
  [LegacyUnforgeable] attribute USVString hostname;
  [LegacyUnforgeable] attribute USVString port;
  [LegacyUnforgeable] attribute USVString pathname;
  [LegacyUnforgeable] attribute USVString search;
  [LegacyUnforgeable] attribute USVString hash;

  [LegacyUnforgeable] undefined assign(USVString url);
  [LegacyUnforgeable] undefined replace(USVString url);
  [LegacyUnforgeable] undefined reload();

  [LegacyUnforgeable, SameObject] readonly attribute DOMStringList ancestorOrigins;
};
location.toString()
location.href

Location/href

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

Location/toString

Support in all current engines.

Firefox22+Safari1+Chrome52+
Opera?Edge79+
Edge (Legacy)12+Internet Explorer11
Firefox Android22+Safari iOS1+Chrome Android52+WebView Android52+Samsung Internet6.0+Opera Android?

Returns the Location object's URL.

Can be set, to navigate to the given URL.

location.origin

Location/origin

Support in all current engines.

Firefox21+Safari5.1+Chrome8+
Opera15+Edge79+
Edge (Legacy)12+Internet Explorer11
Firefox Android21+Safari iOS5+Chrome Android18+WebView Android37+Samsung Internet1.0+Opera Android14+

Returns the Location object's URL's origin.

location.protocol

Location/protocol

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

Returns the Location object's URL's scheme.

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

location.host

Location/host

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

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

Location/hostname

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

Returns the Location object's URL's host.

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

location.port

Location/port

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

Returns the Location object's URL's port.

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

location.pathname

Location/pathname

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

Returns the Location object's URL's path.

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

location.search

Location/search

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

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

Location/hash

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera12.1+Edge79+
Edge (Legacy)12+Internet Explorer3+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android12.1+

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)

Location/assign

Support in all current engines.

Firefox1+Safari3+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer5.5+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

Navigates to the given URL.

location.replace(url)

Location/replace

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer5.5+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

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

location.reload()

Location/reload

Support in all current engines.

Firefox1+Safari1+Chrome1+
Opera3+Edge79+
Edge (Legacy)12+Internet Explorer5.5+
Firefox Android4+Safari iOS1+Chrome Android18+WebView Android1+Samsung Internet1.0+Opera Android10.1+

Reloads the current page.

location.ancestorOrigins

Location/ancestorOrigins

FirefoxNoSafari6+Chrome20+
Opera15+Edge79+
Edge (Legacy)NoInternet ExplorerNo
Firefox AndroidNoSafari iOS6+Chrome Android25+WebView Android4.4+Samsung Internet1.5+Opera Android14+

Returns a DOMStringList object listing the origins of the ancestor browsing contexts, from the parent browsing context to the top-level browsing context.

A Location object has an associated relevant Document, which is this Location object's relevant global object's browsing context's active document, if this Location object's relevant global object's browsing context is non-null, and null otherwise.

A Location object has an associated url, which is this Location object's relevant Document's URL, if this Location object's relevant Document is non-null, and about:blank otherwise.

A Location object has an associated ancestor origins list. When a Location object is created, its ancestor origins list must be set to a DOMStringList object whose associated list is the list of strings that the following steps would produce:

  1. Let output be a new list of strings.

  2. Let current be the browsing context of the Document with which this Location object is associated.

  3. Loop: If current has no parent browsing context, jump to the step labeled end.

  4. Let current be current's parent browsing context.

  5. Append the serialization of current's active document's origin to output.

  6. Return to the step labeled loop.

  7. End: Return output.

To Location-object navigate, given a URL url and an optional history handling behavior historyHandling (default "default"):

  1. Let browsingContext be the current global object's browsing context.

  2. Let sourceBrowsingContext be the incumbent global object's browsing context.

  3. If browsingContext is still on its initial about:blank Document, then set historyHandling to "replace".

  4. If this Location object's relevant Document is not yet completely loaded, and the incumbent global object does not have transient activation, then set historyHandling to "replace".

  5. Navigate browsingContext to url, with exceptionsEnabled set to true, historyHandling set to historyHandling, and the source browsing context set to sourceBrowsingContext.

The href attribute's getter must run these steps:

  1. If this Location object's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  2. Return this Location object's url, serialized.

The href attribute's setter must run these steps:

  1. If this Location object's relevant Document is null, then return.

  2. Parse the given value relative to the entry settings object. If that failed, throw a TypeError exception.

  3. Location-object navigate given the resulting URL record.

The href attribute setter intentionally has no security check.

The origin attribute's getter must run these steps:

  1. If this Location object's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  2. Return the serialization of this Location object's url's origin.

The protocol attribute's getter must run these steps:

  1. If this Location object's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  2. Return this Location object's url's scheme, followed by ":".

The protocol attribute's setter must run these steps:

  1. If this Location object's relevant Document is null, then return.

  2. If this Location object's relevant Document's origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  3. Let copyURL be a copy of this Location object's url.

  4. Let possibleFailure be the result of basic URL parsing the given value, followed by ":", with copyURL as url and scheme start state as state override.

    Because the URL parser ignores multiple consecutive colons, providing a value of "https:" (or even "https::::") is the same as providing a value of "https".

  5. If possibleFailure is failure, then throw a "SyntaxError" DOMException.

  6. If copyURL's scheme is not an HTTP(S) scheme, then terminate these steps.

  7. Location-object navigate to copyURL.

The host attribute's getter must run these steps:

  1. If this Location object's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  2. Let url be this Location object's url.

  3. If url's host is null, return the empty string.

  4. If url's port is null, return url's host, serialized.

  5. Return url's host, serialized, followed by ":" and url's port, serialized.

The host attribute's setter must run these steps:

  1. If this Location object's relevant Document is null, then return.

  2. If this Location object's relevant Document's origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  3. Let copyURL be a copy of this Location object's url.

  4. If copyURL's cannot-be-a-base-URL is true, then return.

  5. Basic URL parse the given value, with copyURL as url and host state as state override.

  6. Location-object navigate to copyURL.

The hostname attribute's getter must run these steps:

  1. If this Location object's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  2. If this Location object's url's host is null, return the empty string.

  3. Return this Location object's url's host, serialized.

The hostname attribute's setter must run these steps:

  1. If this Location object's relevant Document is null, then return.

  2. If this Location object's relevant Document's origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  3. Let copyURL be a copy of this Location object's url.

  4. If copyURL's cannot-be-a-base-URL is true, then return.

  5. Basic URL parse the given value, with copyURL as url and hostname state as state override.

  6. Location-object navigate to copyURL.

The port attribute's getter must run these steps:

  1. If this Location object's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  2. If this Location object's url's port is null, return the empty string.

  3. Return this Location object's url's port, serialized.

The port attribute's setter must run these steps:

  1. If this Location object's relevant Document is null, then return.

  2. If this Location object's relevant Document's origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  3. Let copyURL be a copy of this Location object's url.

  4. If copyURL cannot have a username/password/port, then return.

  5. If the given value is the empty string, then set copyURL's port to null.

  6. Otherwise, basic URL parse the given value, with copyURL as url and port state as state override.

  7. Location-object navigate to copyURL.

The pathname attribute's getter must run these steps:

  1. If this Location object's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  2. Let url be this Location object's url.

  3. If url's cannot-be-a-base-URL is true, then return url's path[0].

  4. If url's path is empty, then return the empty string.

  5. Return "/", followed by the strings in url's path (including empty strings), separated from each other by "/".

The pathname attribute's setter must run these steps:

  1. If this Location object's relevant Document is null, then return.

  2. If this Location object's relevant Document's origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  3. Let copyURL be a copy of this Location object's url.

  4. If copyURL's cannot-be-a-base-URL is true, then return.

  5. Set copyURL's path to the empty list.

  6. Basic URL parse the given value, with copyURL as url and path start state as state override.

  7. Location-object navigate to copyURL.

The search attribute's getter must run these steps:

  1. If this Location object's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  2. If this Location object's url's query is either null or the empty string, return the empty string.

  3. Return "?", followed by this Location object's url's query.

The search attribute's setter must run these steps:

  1. If this Location object's relevant Document is null, then return.

  2. If this Location object's relevant Document's origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  3. Let copyURL be a copy of this Location object's url.

  4. If the given value is the empty string, set copyURL's query to null.

  5. Otherwise, run these substeps:

    1. Let input be the given value with a single leading "?" removed, if any.

    2. Set copyURL's query to the empty string.

    3. Basic URL parse input, with null, the relevant Document's document's character encoding, copyURL as url, and query state as state override.

  6. Location-object navigate to copyURL.

The hash attribute's getter must run these steps:

  1. If this Location object's relevant Document is non-null and its origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  2. If this Location object's url's fragment is either null or the empty string, return the empty string.

  3. Return "#", followed by this Location object's url's fragment.

The hash attribute's setter must run these steps:

  1. If this Location object's relevant Document is null, then return.

  2. If this Location object's relevant Document's origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  3. Let copyURL be a copy of this Location object's url.

  4. Let input be the given value with a single leading "#" removed, if any.

  5. Set copyURL's fragment to the empty string.

  6. Basic URL parse input, with copyURL as url and fragment state as state override.

  7. Location-object navigate to copyURL.

Unlike the equivalent API for the a and area elements, the hash attribute's setter does not special case the empty string to remain compatible with deployed scripts.


When the assign(url) method is invoked, the user agent must run the following steps:

  1. If this Location object's relevant Document is null, then return.

  2. If this Location object's relevant Document's origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  3. Parse url relative to the entry settings object. If that failed, throw a "SyntaxError" DOMException.

  4. Location-object navigate given the resulting URL record.

When the replace(url) method is invoked, the user agent must run the following steps:

  1. If this Location object's relevant Document is null, then return.

  2. Parse url relative to the entry settings object. If that failed, throw a "SyntaxError" DOMException.

  3. Location-object navigate given the resulting URL record and "replace".

The replace() method intentionally has no security check.

When the reload() method is invoked, the user agent must run the appropriate steps from the following list:

If this Location object's relevant Document is null

Return.

If this Location object's relevant Document's origin is not same origin-domain with the entry settings object's origin

Throw a "SecurityError" DOMException.

If the currently executing task is the dispatch of a resize event in response to the user resizing the browsing context

Repaint the browsing context and return.

If the browsing context's active document is an iframe srcdoc document JAKE-TODO: might be able to remove this if history entries support srcdoc properly

Reprocess the iframe attributes of the browsing context's container.

Otherwise

Navigate the browsing context to this Location object's relevant Document's URL, with exceptionsEnabled set to true, historyHandling set to "reload", and the source browsing context set to the browsing context being navigated.

When a user requests that the active document of a browsing context be reloaded through a user interface element, the user agent should navigate the browsing context to the same resource as that Document, with historyHandling set to "reload". In the case of non-idempotent methods (e.g., HTTP POST), the user agent should prompt the user to confirm the operation first, since otherwise transactions (e.g., purchases or database modifications) could be repeated. User agents may allow the user to explicitly override any caches when reloading.


The ancestorOrigins attribute's getter must run these steps:

  1. If this Location object's relevant Document is null, then return an empty list.

  2. If this Location object's relevant Document's origin is not same origin-domain with the entry settings object's origin, then throw a "SecurityError" DOMException.

  3. Otherwise, return this Location object's ancestor origins list.

The details of how the ancestorOrigins attribute works are still controversial and might change. See issue #1918 for more information.


As explained earlier, the Location exotic object requires additional logic beyond IDL for security purposes. The Location object must use the ordinary internal methods except where it is explicitly specified otherwise below.

Also, every Location object has a [[DefaultProperties]] internal slot representing its own properties at time of its creation.

7.10.7.1 [[GetPrototypeOf]] ( )
  1. If ! IsPlatformObjectSameOrigin(this) is true, then return ! OrdinaryGetPrototypeOf(this).

  2. Return null.

7.10.7.2 [[SetPrototypeOf]] ( V )
  1. Return ! SetImmutablePrototype(this, V).

7.10.7.3 [[IsExtensible]] ( )
  1. Return true.

7.10.7.4 [[PreventExtensions]] ( )
  1. Return false.

7.10.7.5 [[GetOwnProperty]] ( P )
  1. If ! IsPlatformObjectSameOrigin(this) is true, then:

    1. Let desc be ! OrdinaryGetOwnProperty(this, P).

    2. If the value of the [[DefaultProperties]] internal slot of this contains P, then set desc.[[Configurable]] to true.

    3. Return desc.

  2. Let property be ! CrossOriginGetOwnPropertyHelper(this, P).

  3. If property is not undefined, then return property.

  4. Return ? CrossOriginPropertyFallback(P).

7.10.7.6 [[DefineOwnProperty]] ( P, Desc )
  1. If ! IsPlatformObjectSameOrigin(this) is true, then:

    1. If the value of the [[DefaultProperties]] internal slot of this contains P, then return false.

    2. Return ? OrdinaryDefineOwnProperty(this, P, Desc).

  2. Throw a "SecurityError" DOMException.

7.10.7.7 [[Get]] ( P, Receiver )
  1. If ! IsPlatformObjectSameOrigin(this) is true, then return ? OrdinaryGet(this, P, Receiver).

  2. Return ? CrossOriginGet(this, P, Receiver).

7.10.7.8 [[Set]] ( P, V, Receiver )
  1. If ! IsPlatformObjectSameOrigin(this) is true, then return ? OrdinarySet(this, P, V, Receiver).

  2. Return ? CrossOriginSet(this, P, V, Receiver).

7.10.7.9 [[Delete]] ( P )
  1. If ! IsPlatformObjectSameOrigin(this) is true, then return ? OrdinaryDelete(this, P).

  2. Throw a "SecurityError" DOMException.

7.10.7.10 [[OwnPropertyKeys]] ( )
  1. If ! IsPlatformObjectSameOrigin(this) is true, then return ! OrdinaryOwnPropertyKeys(this).

  2. Return ! CrossOriginOwnPropertyKeys(this).