It's not all that hard to build a React or Angular apps that use proper links along with the browser history API. Designed properly, the apps should be able to load their state and render correctly even when deep-linked to somewhere other than the app's top level.
This isn't a new concern - I remember paying attention to this back in the old days of SPAs using GWT back in 2009/2010.
Unfortunately, many web apps choose to ignore this. On the bright side, lots of them get it right, too.
(Ironically, these days I'm relieved when I see a presentation is posted as a PDF: https://people.apache.org/~xli/presentations/history_Intel_C.... I'd much rather load a PDF than deal with all the shitty and insane ways people have figured out how to show presentations in HTML. Cough SlideShare: https://www.slideshare.net/garyachy/dpdk-44585840)
EDIT: If you mean one of those 20-image slideshows intentionally made to create fake click statistics, I agree that that's absolutely infuriating. But in that case ergothus' comment applies: the real problem is bad faith webdesign in that case.
[0] https://developer.mozilla.org/en-US/docs/Web/API/History#Met...
Broad support for history management is well-established at this point: https://caniuse.com/#feat=history
I suppose it's all a matter of trying to do what will best match user expectations. Or just whatever will make them happiest. Maybe call it the principle of least annoyance.
Of course, if you make an ad supported slideshow app, maybe you want to show one slide per page to get more ad impressions. I suppose that would be the principle of maximum revenue, along with its corollary (from the user's perspective): the principle of maximum indignation.
I'm not saying it isn't useful to bypass that to get back, but then you're literally asking the people that made the bad design decision in the first place to make the good one to let you out - and they likely won't, for the same reasons they gave you that UI in the first place.
What if state should be destroyed when you press the back button? What if I open an image in a photo app, click a button to delete it, and go to a 'deletion successful' page.
Should clicking the back button return me to a page containing the image? A page containing 'this image has been deleted'? The website I was on before I was on the photo app?
Which actions defines a history-worthy state change? Should clicking around a menu generate 10 history events? What about toggling a checkbox? What about an action that changes most of the information on a page? Should that generate a history event? What if that action is bringing an in-app tab to the forefront?
What if there is an obvious history event that should be generated, but there is no good reason for why a user would want to go back to that state?
It doesn't even matter how you answer all of the above questions - other people will have different answers for them, and have different expectations for how the back button should work, on the same app.
Basically, if the "back" button behaves differently than it would have behaved in a functionally similar web app in 1998, it's broken. Web apps in 1998 didn't let you click "back" out of a POST.
The web was not designed for such use, yet we continue to stretch and abuse whats there and wonder why most sites suck and get it wrong.
Should I download a Wells Fargo app to my desktop, so that I can do banking with them? And a Google Docs app? And a Seattle City Lights app? Maybe a Progressive app, so I can manage my insurance policy? And one for the Washington DMV?
How many problems is running random binaries from random developers at those organizations going to give me? How much more expensive is it to develop apps, over websites? How will you make these apps run on Android, IOS, Linux, MacOS, and Windows? [1]
All of these websites have rich app-like functionality. The web was designed as a document store, yes. This is 2018, though - its not used as a document store. It's the place where I do my banking, my shopping, keep my spreadsheets, and make image macros. Turning all of that into non-web apps will just make development more expensive, degrade my user experience, and negatively impact my PC's security.
But hey, the upshot is that the sanctity of the back button will be protected!
[1] Maybe we could sandbox them... And have a cross-platform 'operating system'[2] where they can run. Maybe even have several such 'operating systems', with similar functionality, but built by different vendors. Vendors like Microsoft, Apple, Mozilla, and Google, maybe?
[2] We can even make this 'operating system' support opening static .HTML pages, so that we can 'browse' through them.
These are great questions, but they kind of apply to a different level of the design than my litmus test.
Start with not making it more complicated than it is: browser history is browser state that we should be able to go back to. When this is not the case, it does not go into browser history (strictly speaking about using the JavaScript history API here).
Otherwise, we need to ask and answer questions like the one you posed. And at that point, "does this break the back button?" is a good first question to ask oneself to ensure we think things through and figure out what it is that we are really trying to achieve.
> What if state should be destroyed when you press the back button?
That says something about which state of the current page is going to be stored in the history, not which state of the previous previous pages has been stored.
> What if I open an image in a photo app, click a button to delete it, and go to a 'deletion successful' page.
This is a solved problem! The "deletion successful" message should not be its own page to begin with, that's what makes it look more complicated! A modal pop-up is the right answer here. (tangent: I'm sure we both agree that many problems are caused by trying to fix issues created by using the wrong initial solution)
If all of this happens within a photo app, the app is the page, which we never left; we clicked a button, not a link. App state history is not the same as browsing history, so if, and only if, we want to preserve snapshots of the photo app state, we use replaceState and/or pushState.
In the case where different pages are warranted, for example within a photo gallery on Facebook or Imgur, the pop-up still happens on the page linking to the uploaded-but-now-deleted photo, followed by a redirect to, say, the main gallery. The link to the uploaded photo should then become a 404 page, because it is now an invalid link.
In both cases, the "deletion successful" modal obviously does not need to be preserved in the browser history.
> It doesn't even matter how you answer all of the above questions - other people will have different answers for them, and have different expectations for how the back button should work, on the same app.
And some of those answers will be right, most will be wrong, and some will depend on the desired context. But presenting hypothetical exceptional cases does not prove there is no such thing as really obviously bad design. There are exceptions, but they are just that: exceptions. They don't invalidate the question as a good first guiding principle to start from.
If anything, doing provokes these questions: you came up with them in response to the implied question "what does it mean to break the back button?" That is a lot better than just slapping something together without thinking about it.
What is the state that we can go back to?
Is it the part of the app that we were on, or is it the part of the app + the content? Content these days is dynamic - if its gone, can we really 'go back to' it?
> This is a solved problem! The "deletion successful" message should not be its own page to begin with, that's what makes it look more complicated! A modal pop-up is the right answer here. (tangent: I'm sure we both agree that many problems are caused by trying to fix issues created by using the wrong initial solution)
That's not what's important, though. If 'deletion successful' is not its own page, then imagine that I then navigated to some other part of the app after deleting the image. What should happen when I press the back button?
a) Go to the "Do you want to delete this image" screen.
b) Go to a "No image found" screen.
c) ???
Option a) is misleading, because the image has already been deleted. Option b) is abuse of the back button, because we have not returned to old state.
> In the case where different pages are warranted, for example within a photo gallery on Facebook or Imgur, the pop-up still happens on the page linking to the uploaded-but-now-deleted photo, followed by a redirect to, say, the main gallery. The link to the uploaded photo should then become a 404 page, because it is now an invalid link.
When I click the back button in my browser, I see a cached version of the webpage I previously visited. What you described is not the behaviour I expect, (and is another way of breaking the back button).
> And some of those answers will be right, most will be wrong, and some will depend on the desired context. But presenting hypothetical exceptional cases does not prove there is no such thing as really obviously bad design. There are exceptions, but they are just that: exceptions. They don't invalidate the question as a good first guiding principle to start from.
These aren't edge cases and exceptions. This is trying to shoehorn a leaky abstraction (the browser back button) into a paradigm where it is often inappropriate, surprising, or just plain unworkable (pretty much everything you do in rich webapps). Your operating system doesn't have a 'back' button for that very same reason.
If your app has a consistent (Internally, and with how the rest of the web works) definition of what going 'back' is, great. Implement it. If it doesn't, that's also fine. 'The back button doesn't work in your app' is not, in itself, a sufficient heuristic for a poor design.
This is just not my experience, at all. I'm extremely sensitive to this issue, and its just not something I see all that regularly any more.
Good luck getting a group of people to agree on what "non-broken" back button behavior is.
Unless you mash the back button really quickly ...<sigh>
Cache invalidation is a technical solution, and it could conceivably be done with header magic or something, but the real problem is people thinking the back button undoes history and the server (and, possibly, reality) disagreeing.
Some people don't care about a back button in a single page application and it isn't "trivial" to implement properly. It requires libraries, polyfill support, etc. And in a world where everyone is complaining about js bloat, it should be no surprise why it exists.
I haven't checked in a while, I wonder if this situation improved? A lot of these frameworks market themselves as dead easy, but I always found a gap between the "dead easy start-up" documentation, and the documentation that essentially amounted to "read the source code."
I wouldn't be surprised if most if not all tutorials ignore it as well.
Humble suggestion: design fads.
My own question would be whether this gets taught anywhere. Because if it does, a few someones need to get fired.
My problem is usually the opposite: I constantly stumble upon websites that use ridiculously large fonts like I'm a grandma that tries to read something on an overkillishly-retina display from meters away. However it doesn't usually bother me when I'm browsing from my desktop 'cause I have options to zoom out; however most of mobile layouts feature something like <meta name="viewport" content="..., minimum-scale=1"> (edit: also mentioned in the article albeit in a bit different context), which makes me choose between intensive vertical scrolling in regular mode and constant horizontal scrolling if I "request desktop site". (Yeah, I know, "reader mode"; it's a reasonable hack but I'm not quite satisfied with any of implementations either, and it only works for whatever browser thinks the main body of the page is.)
Is this everyone else's experience? How has web design been taught lately?
Just don't.
PubMed.
https://www.ncbi.nlm.nih.gov/pmc/articles/PMC3968624/
(There's still a legacy fallback.)
There are two choices: don't recreate the state -> people will call each other stupid over the phone because they see different things for the same link,
-or-
Recreate the state -> more money, more time,
-or-
Just don't have links at all. Which is what people usually choose because is faster and cheaper.
What changed was that before, "to do the right thing", i.e. have real links, was the easiest and the cheapest. Now to do the same, you need real developers. Even in Angular there is/was a discussion of where to put the state of the app in the url? put it in the path part of in the hash part? the difference being that the hash is not sent to server. So for search engines all those links are just one actually... Which is ironic because Angular is made by a search engine.
To track clicks.
How do screen readers handle these script-based links? I don't mind it from a "I have working eyes and arms" perspective, but I imagine it's kind of a pain for assisted vision?
I guess it might just bother me so much because it shows a fundamental misunderstanding of how the web works.
There was this hellish twilight area of my learning web dev where I was transitioning from how i thought the internet worked (HTML pages with anchor tags) to how it actually worked in 2015, which is slapped together framework routers that I couldn't fenangle to work with the History API.
I've no idea what people expect right clicking a delete link to open in a new tab to do?
I expect it to issue the delete, and then dump the response to the delete into a new tab rather than navigating away from the page that hosts the delete link.
There might be ten other delete links on the original page, and I don't want to delete-back-delete-back-delete-back, when I can just open all of them in a new tab, then go through the tabs to look for errors.
When you get sick of faking it you look into why there is no way to get browser to send real DELETEs and PUTs and w3c verbiage says "because application developers don't seem to need it" ... because they fake it ... because they have to fake it ... because browser don't do it ... because devs don't need it ...
I wonder why these limitations. Especially since you can get past this with an:
button.addEventHandler('click', () => {
fetch('/path/to/resource', { method: 'DELETE' })
});
which seems way less accessible then to have the method there right there as an attribute.Api-wise that's a reason to mux your puts and deletes in the POST handler and not in the GET handler, since it force the HTML to use buttons rather than links that might get crawled.
<button formmethod="POST">
is better then: <button formmethod="DELETE">
When the former actually calls DELETE behind the scenes. I would think a crawler would prefer the latter, except for the fact that it is invalid (!)Really egregious examples even change the location so that I can copy the URL after clicking, new tab, paste, and hit back in the original, but I can't middle click for a new tab.