[javascript] JS - window.history - Delete a state

Using the html5 window.history API, I can control the navigation pretty well on my web app.

The app currently has two states: selectDate(1) and enterDetails(2).

When the app loads, I replaceState and set a popState listener:

history.replaceState({stage:"selectDate",...},...);
window.onpopstate = function(event) {
    that.toStage(event.state.stage);
};

When a date is selected and the app moves to stage 2 I push state 2 onto the stack:

history.pushState({stage:"enterDetails",...},...);

This state is replaced anytime details change so they are saved in the history.

There are three ways to leave stage 2:

  • save (ajax submit)
  • cancel
  • back button

The back button is handled by the popstate listener. The cancel button pushes stage 1 so that the user can go back to the details they were entering the back button. These both work well.

The save button should revert back to stage 1 and not allow the user to navigate back to the details page (since they already submitted). Basical, y it should make the history stack be length = 1.

But there doesn't seem to be a history.delete(), or history.merge(). The best I can do is a history.replaceState(stage1) which leaves the history stack as: ["selectDate","selectDate"].

How do I get rid of one layer?

Edit:

Thought of something else, but it doesn't work either.

history.back(); //moves history to the correct position
location.href = "#foo"; // successfully removes ability to go 'forward', 
                       // but also adds another layer to the history stack

This leaves the history stack as ["selectDate","selectDate#foo"].

So, as an alternative, is there a way to remove the 'forward' history without pushing a new state?

This question is related to javascript html browser-history

The answer is


There is no way to delete or read the past history.

You could try going around it by emulating history in your own memory and calling history.pushState everytime window popstate event is emitted (which is proposed by the currently accepted Mike's answer), but it has a lot of disadvantages that will result in even worse UX than not supporting the browser history at all in your dynamic web app, because:

  • popstate event can happen when user goes back ~2-3 states to the past
  • popstate event can happen when user goes forward

So even if you try going around it by building virtual history, it's very likely that it can also lead into a situation where you have blank history states (to which going back/forward does nothing), or where that going back/forward skips some of your history states totally.