Fork me on GitHub
#architecture
<
2023-09-04
>
Drew Verlee03:09:55

I would like some feedback on the idea of front-end/browser application routing. To start, as an example of routing, I mean when a user clicks a button and a drawer opens, or they move from their page to a friend page. The curious part to me is, why do we consider opening a drawer a different "route" but not, for instance, expanding the user profile to show more information? From my perspective, there was an action, and the information on the screen changed. Another aspect of routing is that it's often reflected URL. If you visit your profile page the URL would reflect that, maybe something like: /user/1/profile. I have always felt the goal of this synchronization is ambiguous. Is the intent to help the user save the application state, e.g book mark their profile page. I feel like if a user is bookmarking a view then might there might be some design flaw in the app? Something better handled by making that view accessible on their homepage in the first place. Or at least, reachable in just as many clicks as opening their bookmarks tab. Sometimes developers suggest the URL has application state so that users can share the URL and reach that state. And while this is something users can do, I don't recall designing routing tables with that use case in mind. Some common problems that sharing URLs tends to run into are that they often contain private information, and the URL itself isn't wasn't designed with a user reading it in mind. Also, it's easy to see how oversharing in the URL can be an issue e.g: sharing personal information in a URL like: /underwear?size=45. And as far as letting the users share information, it doesn't seem like a very good tool compared to the alternatives E.g If you want your users to share some pictures of with their friends, you don't encourage them to copy-paste URLs, you have them click on the pictures and select "share". Then the friend will get a notification about it, and see that a photo is now available for them to view. The best I can tell, this practice of capturing state in the URL is primarily a holdover from a time when the request to the server was sent using the URL directly, But every app I have worked on is using another protocol (e.g graphql), so only the frontend url interpreter is using that URL. So i'm i missing part of the picture here? Are you using routing tables to achieve some other goal or concern then the ones i outlined above?

seancorfield04:09:34

Part of the issue is that browsers provide their own history and "back" (and "forward") buttons. So there's an expectation that you as a user can navigate via the browser's controls (since that's how the web has worked for decades). The only way you can do that is via pushing URLs into the "history", which inherently means the URLs must control the state of the app to some degree. So it's not about developers, it's about users and their expectations.

seancorfield04:09:44

Yes, as a side-effect of this, users can save bookmarks to "internal" app state -- but that's purely an implementation detail of how browsers work regarding history and back/forward controls and what apps have to do to support that. It's an interesting dance to ensure your URLs don't leak personal information and can't auto-login (so sharing a URL doesn't let other people into your account) while still making the URLs useful enough for anyone who bookmarks them -- since the browser experience makes users expect that they can bookmark any URL and, as long as they are logged in, can go back to that bookmark any time they want.

seancorfield04:09:21

In answer to your initial Q: > why do we consider opening a drawer a different "route" but not, for instance, expanding the user profile to show more information? That very much depends on the application itself and whether it considers either or both of those to be important "state" that a user might expect to be tied into the "URL-as-bookmark" model they have of the web.

Drew Verlee05:09:30

If we want some events to be tracked by the browser then wouldn't it be more straight forward to mark them directly? View comments - track Expand comment - track Write comment - track (warn user they will lose comment if they hit back) Click up vote - don't track.

lukasz14:09:40

Let me put my product management hat on 😉 tracking is very much business and product specific and you need to be very clear about what you want to track and why. In the past I made a mistake of instrumenting everything only to find few weeks later that the event tracking we shipped was next to useless and had to ship tracking plan v2 Nowadays I don’t do client side tracking if possible and infer behaviors from what we gather on the backend - but again, it very much depends on the larger context. Regarding URLs - as Sean said, browser history and users expectations around it are what’s important.

Drew Verlee15:09:55

To clarify,in my example, a tracked event is one that's tracked so that it's available when the user hits the back button.

lukasz15:09:42

Ah that event tracking! In that case your client-side router should handle this for you - you define the routes and it should manage the history transparently (once configured, it's been a while)

seancorfield16:09:05

In the pure JS world, you decide what goes into the browser history so you control what back/forward in the browser means and how much state you encode in all of that. Users have an expectation that those buttons will "work" regardless of whether they're on a web site or in a web app. I don't know how routing libraries work client-side but there are definitely some operations where you will want the history updated and some where you won't. Observability is a whole different thing (as Lukas indicated) so "events" and "tracking" are not normally the terms used for navigation history, which is what you're talking about @U0DJ4T5U1