What do disabling the back button, the search for the Holy Grail, and the search for the Fountain of Youth have in common?

A. They have been made into major motion pictures
B. Many have died trying
C. They are impossible
D. This is stupid, get to the point

Fine, D it is then. Gee, lighten up will you? Okay, on to it then. Today while jogging, I received a text from a colleague who was looking for a way to disable the back button. I responded that I thought it was impossible, and continued running. However I tend to inadvertently solve coding problems while jogging, and the following idea came to me.

Use cases

It’s impossible to absolutely, unequivocally prevent someone from traversing their browser history. If you have-to-or-people-will-die, either redesign your application or accept that death is inevitable. With that knowledge, here are some use cases that are good candidates for this method:

  • You want to mitigate accidental form resubmission
  • The previous page is full of javascript-generated content, and going “back” would confuse users
  • You only need to hit the 99% mark in terms of prevention, to mitigate annoyances and minor problems
  • You need very strong prevention – this is useful in combination with other methods

You get the idea. There are workarounds, like bringing up the full history list and going far enough back. But we can prevent Joe User from simply clicking “Back” (or hitting “Backspace”, etc.).

It isn’t window.onbeforeunload

Everyone starts there, including me. It only ends in tears and madness. window.onbeforeunload can be used to show warnings and frighten the user into clicking “Cancel”, but it can’t prevent the user from leaving.

It’s window.onhashchange


# Inform the target page, with a url hash, that it can't go back
<form action="page2.html#no-back" method="post" />
  <input type="text" name="data" value="The data" />
  <input type="submit" value="Send data" />


// It works without the History API, but will clutter up the history
var history_api = typeof history.pushState !== 'undefined'

// The previous page asks that it not be returned to
if ( location.hash == '#no-back' ) {
  // Push "#no-back" onto the history, making it the most recent "page"
  if ( history_api ) history.pushState(null, '', '#stay')
  else location.hash = '#stay'

  // When the back button is pressed, it will harmlessly change the url
  // hash from "#stay" to "#no-back", which triggers this function
  window.onhashchange = function() {
    // User tried to go back; warn user, rinse and repeat
    if ( location.hash == '#no-back' ) {
      alert("You shall not pass!")
      if ( history_api ) history.pushState(null, '', '#stay')
      else location.hash = '#stay'

That’s it, pretty simple and self-explanatory. You might want to give the MDN article about manipulating browser history a read.

In real life

In real life, you would probably want to place the JS into a function in a separate file and call it on page load.

Also, your application might do some redirection after form submission, meaning the hash will be lost. In that case, your application will need to know to include the hash in the redirected url.

Let me know of any corrections, improvements, or Broke Back Button: The Movie puns in the comments!