Comment by moojacob
16 days ago
I like React. And I have seriously tried the HTMX/Hotwire camp.
I wanted to make a back button use browser APIs to go back if the coming from the inbox, just link to the inbox otherwise to preserve scrolling. I had to wire the actions from the html to call the function that goes back, then in my controller determine the previous page and send the JS enabled back button or the hard link. My logic was spread out over 3 files!
With React I can have js in a component determine if the previous page was inbox, and based on that value show the back button JSX or the link. ALL IN ONE FILE. One conceptually entity for me to model vs 3 that do other things and this functionally is hammered in.
Is it slower? Definitely. But it makes me happy. Miserable in a corporate React slopbase? Blame your coworkers, it would definitely be worse without it.
> I wanted to make a back button use browser APIs to go back if the coming from the inbox, just link to the inbox otherwise to preserve scrolling. I had to wire the actions from the html to call the function that goes back, then in my controller determine the previous page and send the JS enabled back button or the hard link.
This is why I hate react spas. They're always trying to find some stupid way to break my browsers back button and navigation buttons.
I will always prefer htmx/server rendering with native everything (except the occasional form boosting.)
They are actually speaking to trying to make an in-app back button use the history stack so that it _doesn’t_ “break” your browser’s back button.
The problem with just calling history.back() with no fallback is it will bounce users out of your app (back to Google or wherever they came from) and PMs won’t like that…
`history.back()` shouldn't even exist, it's almost never correct to use it instead of a logical back button that works on the logical navigation structure e.g. going up a level, or to the previous page, etc.
For example, if you are on Page 5, then pressing "back" inside the app should always take you to Page 4. `history.back()` could take you to any page, it's unpredictable.
3 replies →
That's not a react thing, it happened before React was even a thing. It's just self-centered website programmer design.
This has been a non issue when using proper routing libraries that push history entries on the stack properly and render routes from the top of the component tree down.
You hate BAD react SPAs that break the fundamentals of how the web works. Good ones take care to not do that.
React fundamentally doesn't cause this issue either. You can use a different framework than react or even vanilla JS and still produce the same bugs.
> You hate BAD react SPAs that break the fundamentals of how the web works.
But that’s all of them? If Github, Reddit, LinkedIn and Facebook and others are unable to build SPAs that don’t constantly break the fundamentals while also choking the browser, maybe it is a tech problem.
2 replies →
Sure, but the internet is majority bad SPAs vs good ones. Rarely am I delighted by a SPA, but suffer through how poorly it works in bad network conditions, usable back buttons, or otherwise respecting the user.
It’s an absolutely not true that react is especially bad for this behavior.
I think that lots of more traditional websites have very poor back button designs, especially around editing and form submissions. Remember clicking back and the browser prompting for form resubmission? Very poor design since you have no clue how the server will even handle form submissions. Or getting stuck deep in an application, hard to get back to the root. Or, consider encoding current page data that you’re editing into the URL, and back buttons don’t return to root and just strip query params. Often a very frustrating experience.
Often, “go back to what I was doing before” is what I actually want, not “go strictly to the previous state in the URL bar.”
Sure, plenty of people mess that up too, but the reality is that controlling the navigation stack can help you build more useful designs.
My advice would be to only use HTMX for data state related operations. For something like an intelligent back button, unless it depends on resource state do not use the backend to calculate it.
The recommended htmx way would be to hook up an onclick button to inline js or if you dislike that, a function called goBackOrInbox. It can then be something like:
function goBackOrInbox() { if (document.referrer) { const path = new URL(document.referrer).pathname; if (path.startsWith('/inbox')) { history.back(); return; } } window.location.href = '/inbox'; }
And if you use that pattern a lot then you can parameterise the function with whatever the route should be.
I never thought about doing that. Thank you.
Isn't the best way to solve the back button question to not be so damned complicated and just make certain that only things which you want to go back to ends up in the history? The whole framing of the problem just screams "structure your thing better and it won't be a problem to solve".
Re-read it. We needed to preserve scroll position when you went back. If you just linked back to the inbox it would kick you to the top of the screen.
That is not how the back button works in a regular browser. Something you are doing is breaking the default behavior. Stop that.
I know there will probably be some complications here and there, but this could be done with Web Components too, right?
Came to ask this myself. Oddly enough, I think they’ve kind of slipped under everyone’s radar.
Yes you could, or even just a vanilla DOM event handler on a button click.
The problem is that you cannot introspect the browser’s history with the history API. So you have to hack your way around that if you want the “go back in history if possible, otherwise navigate to fallback url” behavior. Which I guess is easier if you’re in a react SPA. Or if you’re fully a MPA and can just check document.referrer
There’s a brand new Navigation API that does let you introspect history entries from the same origin, which perfectly addresses the issue.
I wrote a polyfill in order to take advantage of the navigation API for this exact problem: https://github.com/kcrwfrd/navigation-ponyfill