Back Is Not Undo

Going back is not the same as "undo". You may be looking at stale information without realizing it.

The "Back" concept is fine for static content, but falls apart when dealing with dynamic content, such as data entry, dynamic queries, etc. And it is buggy for dynamic content. Some versions of Internet Explorer will ignore changes made by JavaScript but keep those typed in by the user when going back. Very odd behavior. It is as if IE recreates old pages by rerunning logs of user keystrokes, but they forgot to include JavaScript's changes in the mix.

I would just assume disable "Back" for dynamic web apps. "Real" client/server GUI apps rarely had, or needed, anything like that.

Or not. EclipseIde has had back/forward for navigating editors (and is as such quite similar to web documents). However, they have recently started extending this concept to several other areas, including the preferences menu. It is also useful to note that the undo/redo capability of most applications is precisely a back/forward type command; it also suffers from the same complaints, and many of the same solutions have been applied:
  • Any text editor where one can edit (including using undo/redo), and then use undo repeatedly until one has undone every change one made in the session.
  • Change list based undo in image editing apps (Gimp / Photoshop comes to mind).

Indeed, "real" gui apps have so long needed such behaviour that it almost completely integral to how those applications work.

-- WilliamUnderwood


Well, that refactoring seems to have mangled my text a bit... but such is life :)

"Going back is not the same as "undo". You may be looking at stale information without realizing it."

Such is a weakness of the implementation of back/forward. The abstraction it presents is precisely that of undo. How many times has a naive user submitted something, then tried to 'undo' it by hitting 'back'? It is undoing the action of visiting another page. Unfortunately, this doesn't necessarily have any effect on what the server has done, much as if I make a change to a configuration file and later undo it. My undoing the change has no effect on any decisions made on the basis of that file.

In other words: back is undo in the scope of "what page am I viewing". Any additional scope is coincident, even if desirable.

-- WilliamUnderwood


"There are four things one cannot take back: the past life, a sped arrow, a spoken word and neglected opportunities." - but sometimes it'd sure be nice. 'Undo' is easy so long as you're in a domain you control entirely, but that's rarely the case when working with the real world.


Browsers tend to do a reasonable job differentiating the two, based on whether pages were generated with POST or GET. Any actions that cause changes on the server should be performed with a POST, and the browser usually makes it clear that those actions can not be undone with the back button. Actions performed with GET, on the other hand, can be undone with the back button, since the only change was client-side to begin with. AspDotNet and some other framework make this easier to deal with through "view state" information.

That's not a good solution. The good solution is to have separate and independent back and undo functionality. For that, you need to maintain separate visits and actions stacks. And while you're at it, make them CactusStacks. There are innumerable situations where both functions are required.

And if web browsers weren't so utterly broken that you can't actually do anything using them then both functions would be required of web browsers. Overloading these two completely different concepts is just stupid. But it's rather typical that instead of fixing the interface to fit the application, programmers would break the application to fit the interface.

Right, it isn't a good solution for the big picture. But those limitations come from HTTP, not individual browsers. HTTP doesn't have a way to express undo functionality. If it did, I'm sure you would see browsers designed a bit differently. Laying the blame on "programmers" isn't exactly fair - programmers know that the situation is less than ideal, but with established standards like HTTP, HTML, etc, change doesn't happen overnight.

Undo shouldn't exist as a concept at the lower protocol layer, so it is perfectly proper for HTTP, FTP and any other protocol at that layer of the network stack to not have those concepts built in. And just because it is proper for those lower-level protocols to not have undo, doesn't mean that the higher level layer developers (the web browser developers) can be forgiven for sticking strictly to the lower level layer. They can't be forgiven for being narrow-minded programmers who didn't add any functionality above and beyond the lower layer but chose rather to dumb it all down to the lowest common denominator. Nor can they be forgiven for the sheer arrogance of working at the HCI layer without knowing a single solitary fact of human-computer interaction.

FTP in particular would have benefitted from having separate undo and visits stacks. It would also have benefitted from DirectManipulation so that a user could drag and drop objects in an FTP site off the web browser, or even to the web browser. And the fact remains that web browsers don't do that. And there is absolutely no excuse why they don't do that. There is a reason for it. And that reason is that programmers make incompetent designers and programmers are too stupid to realize that they make incompetent designers. But this is not an excuse, it's an indictment (well, the stupid part anyways).

The idea that a web browser operates at the HTTP layer, instead of above it, and so is constrained by the HTTP protocol, or even by HTML, is an excellent example of typical programmer thinking. It manages to completely misrepresent how the system works in order to get the lazy, stupid and evil programmers off the hook. The sick part of all this is that perfectly competent programmers routinely engage in this type of thinking. In contrast, a competent interaction designer cannot misconceive or misrepresent the system by definition; to do so would prove their incompetence. -- RK


Web servers using the ContinuationPattern, like SeasideFramework, offer elegant support for the back button. (But don't necessarily address the "undo" issue.)


RedirectAfterPost can help with many of the challenges encountered when creating a web application that should be sensibly navigable in the presence of back/forward/refresh/goto-index-in-history operations.


Just take the back / forward functionality out of web browsers (and JavaScript).


I feel like this is a moronic discussion. "Back" is going to be there. When you're browsing the web, and you come along to a page that disables your back button, you get angry. That's why nobody does this anymore.

"Back" is exactly what it says it is. When I'm working on a multi-page form and I click the back button, I expect (and deserve) to go back and work from where I was. When I am using any sort of list interface, like search results, and I click the back button, I damn well better end up on the same search page I left. If you don't feel like this is your responsibility as a web designer, then I recommend FlippingBurgers instead.


Please be careful of being HolierThanThou? on this matter. If a user is on page 4 of a wizard and has added three rows to a table on the form, what will she expect happen when clicking the browser's back button? Will she think those three rows will be undone? Or will she think she is navigating back to page 3 of the wizard without an undo?

Now, what is her expectation when she multi-steps back?

Or, what is her expectation if she presses the refresh button after adding a row to the current page? Should nothing happen or should another row be added?

I put it to you this matter isn't just about being competent. There is no strict definition of such behaviours. And even if there was, I suspect there is some tension between browser behavior and desired interactions. For example, depending on your answers to what the interaction should be, it might demand the need for caching directives on responses. But caching responses on authenticated sites with sensitive data is not desirable (as it enables possible information disclosure even after a user has logged out if they haven't closed the browser on a shared machine).

Finally, there is not enough abstraction to support any such interaction standard (should one even be developed) in the current set of web frameworks for keeping state in sync between browser, web server cache and source data stores.


EditText of this page (last edited November 7, 2009) or FindPage with title or text search