In Single Page Applications, it's common to update the URL when navigating, and re-render based on the new URL. This can happen when the user hits the back and forward button, clicks on an anchor tag, or does something that pushes a new state on the history object.

The consensus for detecting any kind of url change though is to poll every so many milliseconds. It seems that this is because while users can add an EventListener to popstate and hashchange, we still can't listen to pushstate.

If an onpopstate event exists (which is used for navigating with the back and forward button), why doesn't an onpushstate event exist?

If onpopstate has existed for so long, and there's no evidence of an onpushstate in the works, I imagine that it was a conscious decision. Does that mean that adding it would enforce bad programming or patterns?

  • 2
    Most likely "onpushstate" doesn't exist because it's assumed that you know when you're pushing the state. Events are for informing you of things that you have no control over, like the user hitting the forward and back button. If a library pushes the state, the library should have an event to inform you, but the browser doesn't need to. – Kevin Fee Jun 28 '17 at 23:53
  • @KevinFee you can similarly say that the caller of onpopstate can't be in the pages JS, and has to be provided by the browser, but the caller of onpushstate can, which is roughly what the answer in the SO link does – Caleth Jun 29 '17 at 9:16

Here is the rationale:

Under normal circumstances, if you start at page A, pushstate to page B, refresh, and go back to A, we don't change the document -- the document you got from refreshing B gets a popstate. But if you get a response code of 400 or greater when refreshing B, we consider it to be a different document. If the refresh of B returned, for instance, a 404, then we'd actually load A's document when we go back.

If you're at A, push/replace state to B, and then navigate to C (by setting document.location, clicking a link, etc), we send B as the HTTP referer. But if you're at A, navigate to B, pushstate to C, pushstate to D, then refresh D, we send B as the HTTP referer, because pushstates aren't really navigations.


| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.