Hacker Newsnew | past | comments | ask | show | jobs | submit | thijsvandien's commentslogin

While I like this approach as well, these URLs ending up in the browser history isn’t ideal. Autocomplete when just trying to go to the site causes some undesired state every now and then. Maybe query params offer an advantage over paths here.


I think it’s a “use the right tool for the job” thing. Putting ephemeral information like session info in URLs sucks and should only be done if you need to pass it in a get request from a non-browser program or something, and even then I think you should redirect or rewrite the url or something after the initial request. But I think actual navigational data or some sort of state if it’s in the middle of an important action is acceptable.

But if you really just want your users to be able to hit refresh and not have their state change for non-navigational stuff like field contents or whatever, unless you have a really clear use case where you need to maintain state while switching devices and don’t want to do in server-side, local storage seems like the idiomatic choice.


JS does have features for editing the history, but it's a trade-off of not polluting the history too much while still letting the user navigate back and forth


I'm glad to see that prismjs site mentioned by the blog is doing the right thing - when it updates the URL, it replaces the current history item.


Does that handle back button correctly? Nothing more annoying that sites/apps that overwrites the history incorrectly, so when you press the back button it goes to the entry before you entered the website/app, rather than back into what you were doing in the website/app.

Both approaches (appending/rewriting) have their uses, the tricky part is using the right thing for the right action, fuck up either and the experience is abysmal.


It’s definitely possible to make a really stellar experience, but that winds up being the exception. The URL and history state are sort of “invisible” elements of the user experience but require thoughtful care and attention to what the user expects/wants at each step, a level of attention which is already a rarity in web development even in the most visible parts of a page…so frequently the history/back button stuff just totally sucks.


Yeah, in my experience you only get great stuff when both product and engineering has equal care for the final experience. If either parties lack care, you'll miss stuff, particularly things that are "invisible" as you say.


It's pretty weird, my impression is that the APIs are flexible enough to implement most sane behaviors, but websites keep managing to mess it all up. Perhaps it's just one of those things that no one bothers re-testing as the codebase changes.


In my experience, the problem is two-fold. First product managers/owners don't consider the URIs, so it ends up not being specified. They say "We should have a page when user clicks X, and then on that page, user can open up modal Y", but none of it is specified in terms of what happens with the URIs and history.

Then a developer gets the task to create this, and they too don't push back on what exact URIs are being used, nor how the history is being treated. Either they don't have time, don't have the power to send back tasks to product, simply don't care or just don't think of it. They happily carry along creating whatever URIs make sense to them.

No one is responsible for URLs, no one considers that part of UX and design, so no one ends up thinking about it, people implement things as they feel is right, without having a full overview over how things are supposed to fit together.

Anyways, that's just based on my experience, I'm sure there are other holes in the process that also exacerbates the issue.


As a UX designer, this is a failure of the UX designers, IMO. If you're a UX designer for web, you should be aware of web technology and be thinking about these things. Even if you don't know enough to fully specify it, you should be able to enough such that you can have conversations with a developer to work together to fully spec it out.

That said, I've also worked with some developers that didn't like intruding on their turf, so to speak. Though I've also worked with others that were more than happy to collaborate and very proactive about these sorts of things.

Furthermore, as a UX designer this is the sort of topic that we're unlikely to be able to meaningfully discuss with PMs and other stakeholders as it's completely non-visual and often trying to bring this up with them and discuss it ends up feeling like pulling teeth and them wondering why we're even spending time on it. So usually it just ended up being a discussion between me and the developers with no PM oversight.


Web developers should make it a habit to ask/require URL structures be part of the spec.

I've had people be surprised by the request because its something they don't usually consider, but I've never had anyone actually push back on it.


Nothing weird about it, you see people arguing right here whether a site should add a new history entry when a filter is set.

Interacting with the URL from JS within the page load cycle is inherently complex.

For what it's worth, I'd also argue that the right behavior here is to replace.

But that of course also means that now the URL on the history stack for this particular view will always have the filter in it (as opposed to an initial visit without having touched anything).

Of course the author's case is the good/special one where they already visited the site with a filter in the URL.

But when you might be interested in using the view/page with multiple queries/filters/paramerers, it might also be unexpected: for example, developers not having a dedicated search results page and instead updating the query parameters of the current URL.

Also, from the history APIs perspective, path and query parameters are interchangeable as long as the origin matches, but user expectations (and server behavior) might assign them different roles.

Still, we're commenting on a site where the main view parameter (item ID, including submission pages) is a query parameter. So this distinction is pretty arbitrary.

And the most extreme case of misusing pushState (instead if replace) are sites where each keystroke in some typeahead filter creates a new history entry.

All of this doesn't even touch the basic requirement that is most important and addressed in the article: being able to refresh the page without losing state and being able to bookmark things.

Manually implementing stuff like this on top of a basic routing functionality (which should use pushState) in an SPA is complex very quickly.


> But that of course also means that now the URL on the history stack for this particular view will always have the filter in it (as opposed to an initial visit without having touched anything).

I would have one state for when the user first entered the page, and then the first time they modify a filter, add a 2nd state. From thereon, keep updating/replacing that state.

This way if the user clicks into the page, and modifies a dozen things they can

1. Refresh and keep all their filters, or share with a friend 2. Press back to basically clear all their filters (get back to the initial state of the page) 3. Only 1 more press of back to get back to where-ever they came from


I agree, this would be a good approach.

Unless of course, you initially visited the page with a stateful URL.


My personal take would be if it takes you to what's basically another page (such as the entire page being rewritten), then involve browser history.


Yeah, lichess does this.

On lichess.org/analysis, each move you make adds a history item, lichess.org/analysis#1, #2, and so on.

Pretty annoying.


Browser autocomplete behavior is reliably incorrect and infuriating either way, so it's not a good reason to avoid the utility of having bookmarkable/sharable urls.


Yeah it's an annoyance more than it helps. I always disable it.


I do as well - it's just irritating.

Same with search ahead.


Mixed feelings about this. The apps were great and it's always uncomfortable when the future becomes uncertain due to a big acquisition. So far, it seems it could've gone worse. Their business model makes sense. I like that everything got integrated now, because Photo, Designer and Publisher being separate with so much overlap didn't feel natural. Hate the new logo, though... Some elegance was definitely lost.


There's this Silicon app that scans your disk for them: https://github.com/DigiDNA/Silicon.


Very unfortunate how from json lazy import dumps would result in backward compatibility issues. It reads much better and makes it easier to search for lazy imports, especially if in the future something else becomes optionally lazy as well.


Error(error) -> Error(error) has strong if err != nil { return err; } vibes, and I don't consider that a good thing.


No, it doesn't have strong if err != nil { return err; } vibes.

Pattern matching on Ok/Error is one of the best known error handling, while go error handling is one of the worst. They are about as far from each other as possible.


Interesting, I find myself thinking the exact opposite.


That's what Gleam's use expressions[1] are for (the last example is exactly this case). Most languages with the same heritage as Gleam have grown a similar syntactical feature, such as OCaml's binding operators or F#'s computation expressions. Although I appreciate how simple Gleam's is while having similar power.

[1]: https://gleam.run/news/v0.25-introducing-use-expressions/


This is a trivial snippet. Often you will transform/map your error into another type (or deal with it in some way), so it's not so much `if err != nil { return err; }` vibes like you're thinking here.

The beauty here is being compelled to handle both the happy and sad paths. You cannot just pretend the sad path doesn't exist.


Good Go code also wraps errors...


It's not just about wrapping. use-expressions, result.try and result.map eliminate the boilerplate of checking for errors entirely: https://erikarow.land/notes/using-use-gleam


One man's boilerplate is another man's explicitness.


Generally it works well, but what's particularly annoying is that it hides cookie walls, resulting in non-functional websites until I disable content blockers, close the dialog and re-enable them. Not sure if uBlock does any better, though.


Ghostery does the same, but has more fine-grained per-website controls. You can for example turn off just the consent-popup-blocker function for a website while keeping the anti-tracking ad-blocking functions.


Use a bookmarklet to sweep sticky elements for those situation. Not ideal, but works fine.


Use Safari’s own built-in “Hide Distracting Items”. It’s also pretty good at hiding the few remaining “disable your ad blocker to continue” popups Wipr doesn’t yet catch.


This is my only complaint. Most of the websites work fine, but others get stuck. I don’t know if Wipr 2 solved the issue.


We occasionally have this with the actual full uBlock Origin on Firefox as well.

I don't think there's a general solution for this issue. Content blockers need to provide a workaround for each situation, if at all possible.

At least it's possible to contribute to uBlock Origin's filters.


It's literally never used now, because it was taken offline earlier this year.


And before that it was essentially irrelevant and on life support for what, maybe a decade?


Then using .prl in stead wouldn’t have helped much…


Amazing idea. I can hardly stand audio books, and some musical updressing might completely change that. Having a beat to it just makes it so much more fun/engaging/digestible/memorable. Kids are already taught their ABCs using songs for that reason. Why stop there, if all sorts of material could easily be put in that form? Honestly it could revolutionize teaching.


I don’t think so, but they do offer a pure-Python version as well.

https://whenever.readthedocs.io/en/latest/faq.html#how-can-i...


True, but does it suffer in efficiency? I wish they had included the pure Python version in their benchmark.


Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: