Skip to content

A new history API, "app history" #20

Closed

Description

@domenic

Introduction

The web's existing history API is problematic for a number of reasons, which makes it hard to use for web applications. This proposal introduces a new window.appHistory API, which is more directly usable by web application developers to address the use cases they have for history introspection, mutation, and observation/interception.

The proposed API layers on top of the existing API and specification infrastructure, with well-defined interaction points. The main differences are that it is scoped to the current origin and frame, and it is designed to be pleasant to use instead of being a historical accident with many sharp edges. Some notable features:

  • Allow easy conversion of cross-document navigations into single-page app same-document navigations, without fragile hacks like a global click handler.
  • Provide a uniform way to signal single-page app navigations, including their duration.
  • Provide a reliable system to tie application and UI state to history entries. (Better than the existing history.state.)
  • Provides reliable events for notifying the application about navigations through the list of history entries, which they can use to synchronize application or UI state. (Better than the existing popstate and hashchange events.)

Read the complete Explainer.

Feedback

We'd love to hear from the community of developers as to whether this sounds like a worthwhile direction to explore, and in particular whether we should migrate it to the WICG for further discussion in its own dedicated repository.

For any general feedback or questions on the idea, especially any support for developing the idea, please use this thread. For specific technical questions or suggestions on the API, file issues on WICG/app-history where we can work through them in more detail. (Hopefully such questions can move to a dedicated WICG repository once we get general support.)

Activity

  1. frehner commented on Feb 2, 2021

    @frehner

    Whew, finally read through the complete explainer. Thanks for such an exhaustive writeup - I'm not sure I understood it all on my first reading, so I'll probably have to come back and read it a couple times more to really get it, but it is really promising.

    This proposal is exciting, and would certainly remove an issue that the whole single-spa community has to deal with, namely getting multiple application routers to be able to communicate with each other. (Currently the library itself has to monkeypatch history.pushState etc., as well as fire events more frequently than the browser does in order to get things working.)

    I would love to see this get officially picked up and started down the process of refinement and browser adoption. Awesome work ❤️

  2. TheMcMurder commented on Feb 2, 2021

    @TheMcMurder

    I like the approach. It feels a lot more intentional and focusing on applications rather than pages. This would be a significant help in building complex web applications and could help bridge some the divide between the web as a platform for applications and other platforms like iOS and android.

    I would love to see this move forward.

  3. Yay295 commented on Feb 3, 2021

    @Yay295

    Some notes while reading through the explainer:


    appHistory.currentEntry;
    appHistory.updateCurrentEntry();
    appHistory.pushNewEntry();

    These seem a bit more wordy than necessary. I think

    appHistory.current;
    appHistory.update();
    appHistory.push();

    would be just as understandable, and shorter.
    Alternatively instead of appHistory.updateCurrentEntry, having an update method on the history entry itself might be even better. So

    appHistory.current;
    appHistory.current.update();
    appHistory.push();

    This would allow you to update any history entry though, not just the current one, which might be okay, but might not if the URL is changed. Though even that could be okay if it's a future entry and not a past entry, and an exception culd be thrown for a past entry.


    Being able to use the object spread operator on history entries would make some things more readable. For example this line from the explainer for URL fragment navigation

    appHistory.pushNewEntry({ url: urlWithFragment, state: appHistory.currentEntry.state });

    could be

    appHistory.pushNewEntry({ ...appHistory.currentEntry, url: urlWithFragment });

    For the navigation event, how would userInitiated work? If you go back far enough, every action is user initiated. The only things I can think of that might be considered otherwise are navigations that happen on load, or on a timer.

    Is appHistory.currentEntry still the current/previous entry at this point?

    A common scenario in web applications with a client-side router is to perform a "redirect" to a login page if you try to access login-guarded information.

    This should be handled by the server. It might be nice to do it on the client for convenience, but I think there needs to be a warning about using it only on the client.

    For the currententrychange, why does it only react to appHistory.currentEntry changes if its url or state changes? What about its other properties?


    We're still having some discussions about making appHistoryEntry.state into something more structured, like a key/value store instead of an arbitrary JavaScript value.

    I don't know what the discussions so far have been, but I think keeping it as a JavaScript value is cleaner to use.

  4. yoavweiss commented on Feb 3, 2021

    @yoavweiss
    Collaborator

    Thanks all! This seems to have a bunch of support here and elsewhere. I spun up a new repo for this at https://github.com/WICG/app-history

    Happy incubating! :)

  5. domenic commented on Feb 3, 2021

    @domenic
    Author

    Thanks all! I'll close this out now, and work on porting over the issues to the new repo.

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions