Skip to content
This repository was archived by the owner on Aug 21, 2026. It is now read-only.
This repository was archived by the owner on Aug 21, 2026. It is now read-only.

Should this API be able to completely replace window.history? What about window.location? #67

Closed as not planned

Description

@domenic

The explainer details why window.history is an unfortunate API. Given a web developer starting from scratch on a new application, in the glorious future where app history ships everywhere, it seems like it'd be nice if such a web developer could ignore window.history entirely.

With the current design, this is mostly possible, with one exception: the navigation API's control over scroll restoration is not complete compared to history.scrollRestoration. In particular it does not control cross-document scroll restoration.

Should it have that ability? What would that look like?

Other issues to note in the comparison
  • The navigation API, by design, doesn't have any insight into other-frame history entries. If an application needs such capabilities, it would need to coordinate with those frames, either by using iframeEl.contentWindow.navigation for same-origin-domain frames, or postMessage()ing to cross-origin-domain frames.

  • The navigation API takes on a very different model for single-page app navs, as explained in this section. In particular it has no counterpart to history.pushState() or replaceState() which just update the current document's URL; instead you need to intercept a navigation using the navigate event and then use transitionWhile() inside the event handler. This is by design, but it's possible there are cases we haven't thought of yet where just updating the current document's URL is a good idea.

A similar question is, should you be able to use navigation instead of using location? The combined capabilities of navigation.navigate() and navigation.currentEntry.url cover much of Location. However:

  • The convenience getters/setters like location.hash or location.pathname require more work to emulate, e.g. (new URL(navigation.currentEntry.url)).hash, or several lines for the setters.
  • There is no counterpart to location.ancestorOrigins.

Activity

  1. added
    additionA proposed addition which could be added later without impacting the rest of the API
    on Mar 9, 2021
  2. Yay295 commented on Mar 10, 2021

    @Yay295

    The convenience getters/setters like location.hash or location.pathname require more work to emulate, e.g. (new URL(appHistory.current.url)).hash, or several lines for the setters.

    I think this is the main point in favor of keeping location. I expect these are used quite a lot. Was there a reason that appHistory.current.url can't support this though? I feel like it was mentioned in one of these threads but I don't remember the conclusion, if there was one.

  3. kenchris commented on Mar 16, 2021

    @kenchris

    I don't find history.scrollRestoration important, so things don't move around when going forth and back in history - especially for quick user navigations, like clicking back. In a SPA this might only be an issue if the view is somehow unloaded.

    But with virtualized scrolling lists etc, it might not be enough to make this work reliable as you want to know what node/data is shown as well as its viewport offset

  4. Yay295 commented on Mar 16, 2021

    @Yay295

    For scrollRestoration, what about having a method on the navigate event object like evt.preventScrollRestoration()? So it wouldn't be something you set on the history state, but an action you can take when the state changes.

  5. tbondwilkinson commented on Mar 17, 2021

    @tbondwilkinson
    Contributor

    I think having a more expressive scroll restoration API is the direction I would push things in personally.

    Tying scroll restoration to history is awkward, given new improvements like bfcache that make restoring to state more trivial than they used to be.

    If we wanted to have a more expressive API, giving users some control over when scroll positions were saved, and how they were restored, I think would make the API much more useful. But we should also ourselves how much can be accomplished with just a better history API

  6. Yay295 commented on Mar 17, 2021

    @Yay295

    giving users some control over when scroll positions were saved, and how they were restored

    Don't we already have this with window.scrollX, window.scrollY, and window.scroll()? You can store these values whenever you want, and you have full control over when and how they get restored.

  7. kenchris commented on Apr 20, 2021

    @kenchris

    App history takes on a very different model for single-page app navs, as explained in this section. In particular it has no counterpart to history.pushState() or replaceState() which just update the current document's URL; instead you need to intercept a navigation using the navigate event and then use respondWith() inside the event handler. This is by design, but it's possible there are cases we haven't thought of yet where just updating the current document's URL is a good idea.

    I think replaceState etc is useful when updating things like map location (Google Maps like experiences - @denladeside) and video/music player positions. You might click back or forward by mistake and be able to undo mistake without losing position

  8. larsgk commented on Apr 20, 2021

    @larsgk

    App history takes on a very different model for single-page app navs, as explained in this section. In particular it has no counterpart to history.pushState() or replaceState() which just update the current document's URL; instead you need to intercept a navigation using the navigate event and then use respondWith() inside the event handler. This is by design, but it's possible there are cases we haven't thought of yet where just updating the current document's URL is a good idea.

    I think replaceState etc is useful when updating things like map location (Google Maps like experiences - @denladeside) and video/music player positions. You might click back or forward by mistake and be able to undo mistake without losing position

    At Maersk, we are using replaceState for a critical internal enterprise tool to keep a single page application router (with UI and app states) and URL bar in sync (Google Maps style). It makes it easily possible for folks to share (or bookmark) exact views/states.

  9. domenic commented on May 12, 2021

    @domenic
    CollaboratorAuthor

    I've spun off the reload() question into #112

  10. yoavweiss commented on Aug 21, 2026

    @yoavweiss
    Contributor

    Note

    🤖 This comment was written and posted by an AI agent (Claude, running in the Pi coding agent), acting on behalf of @yoavweiss while triaging this repository ahead of archiving it. Migration scope was agreed with @noamr. If this is wrong, please say so and it can be reopened.

    Closing as stale — not resolved.

    The concrete gap identified here — that the navigation API cannot control cross-document scroll restoration, so history.scrollRestoration remains necessary — is still real, and is the narrow, actionable part of this issue. Worth re-filing as specifically that, rather than as the broad "can this fully replace window.history?" framing. cc @domenic

    This repository is being archived. This issue is being closed because it has had no activity in several years and no implementer picked it up — not because the underlying problem was solved or rejected. If it still matters to you, please re-file at whatwg/html with a concrete use case and add the topic: navigation label; a fresh issue with current motivation will get a much better reception than a migrated 2021 thread.


    Where this work lives now: the Navigation API is specified in HTML §7.2.6. Please file new issues at whatwg/html with the topic: navigation label.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    additionA proposed addition which could be added later without impacting the rest of the API

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions