While i agree, the current JS security model rally doesn't allow for distinguishing origin for JS code. Should that ever change, advertisers will just require that you compile their library into the first party js code, negating any benefit from such a security model.
> advertisers will just require that you compile their library into the first party js code, negating any benefit from such a security model.
It will become harder for advertisers to deny responsibility for ads that violate their stated policies if they have to submit the ads ahead of time. Also site operators will need a certain level of technical competence to do this.
More likely, advertisers will need you to insert a "bootloader" that fetches their code and passes it to eval().
Alternatively, they might require you to set up a subdomain with a cname alias pointing to them (or a common CDN), negating any security benefits of such a practice.
> More likely, advertisers will need you to insert a “bootloader” that fetches their code and passes it to eval().
Sounds like legal precedent waiting to be set. “Run our code so that it looks like your code, acts like your code, and has all the same access as your code” seems like it should be a slam dunk if said code ends up doing a Very Bad Thing to your visitors.
But of course that’s assuming common sense, and the law’s relationship with that isn’t always particularly apparent.
There is already plenty of precedent for real-time-served ads which are annoying, or malicious, or install malware; or outright exploit vulnerabilities in the browser.
The advantage would be that I know beforehand, and have the opportunity to test and, possibly, reject, what the advertiser want me to send to someone’s browser.
If it happened browsers started to warn their users about third party JS doing back button history stuff, I have a hunch, that many frontendies would just shrug and tell their visitors: "Oh but for our site it is OK! Just make an exception when your browser asks!" just like we get all kinds of other web BS shoved down our throats. And when the next hyped frontend framework does such some third party integration for "better history functionality" it will become common, leading to skeptics being ridiculed for not trusting sites to handle history.
The History API is pretty useful. It creates a lot of UX improvement opportunities when you're not polluting the stack with unnecessary state changes. It's also a great way to store state so that a user may bookmark or link something directly. It's straight up necessary for SPAs to behave how they should behave, where navigating back takes you back to the previous page.
Yeah but all of this is a symptom of a broader problem rather than reasons why the history API is useful.
SPAs, for example, require so many hacks to work correctly that I often wonder to myself if they’re not really just a colossal mistake that the industry is too blinded to accept.
As a user, I really don't care about the supposed purity or correctness of a website's tech stack. When I click "back" I want to go back to what I think the previous page was.
State management, URL fragment management, reimplementing basic controls...
One that I hate the most is that they first reimplement tabular display with a soup of divs, then because this is slow as a dog, they implement virtualized display, which means they now need to reimplement scrolling, and because this obviously breaks CTRL+F, they end up piling endless hacks to fix that - assuming they bother at all.
The result is a page that struggles to display 100 rows of data. Contrast that with regular HTML, where you can shove 10 000 rows into a table, fully styled, without noticeable performance drop. A "classical" webpage can show couple megabytes worth of data and still be faster and more responsive than typical SPA.
Sounds like you're referring to some specific examples of poorly implemented apps rather than the concept of SPAs as a whole.
For your example, the point of that div soup is that enables behaviours like row/column drag&drop reordering, inline data editing, realtime data syncing and streaming updates, etc. - there is no way to implement that kind of user experience with just html tables.
There's also huge benefit to being able to depend on clientside state. Especially if you want your apps to scale while keeping infra costs minimal.
I get the frustrations you're talking about, but almost all of them are side effects of solutions to very real UX problems that couldn't be solved in any other way.
And to be clear, I'm not saying that people building SPAs when all they needed was a page showing 10,000 rows of static data isn't a problem. It's just a people problem, not an SPA problem.
If you don't manage the history properly in your SPA, pressing the back button could take the user out of the app entirely.
If you don't let web developers manage history/state like this, we'd be going back to the inefficient world of, "every forward/back movement loads a whole page." (With lots of unnecessary round trip messages between the client and server while the user waits for everything to load).
Basically, the ability to manage history is a user-centric feature. It makes the experience better for them.
> If you don't manage the history properly in your SPA, pressing the back button could take the user out of the app entirely.
Yes. And that should be the default behavior: browser buttons should take you through the browser's history. If you keep a in-app state and want the user to navigate through it, you should provide in-app buttons.
Nobody complains that the browser's close button quits the browser instead of the app it's showing, or that the computer's power button shuts down the whole OS and not only the program in the foreground.
Users must be educated. If they have learned that left means "back" and right means "forward", that a star (sometimes a heart) means "remember this for me", and that an underlined checkmark means "download", then understanding the concept of encapsulation shouldn't be too much for them.
Probably referring to using pushState (part of the History API) to update the URL to a bookmarkable fragment URL, or even to a regular path leading to a created document.
> The new history entry's URL. Note that the browser won't attempt to load this URL after a call to pushState(), but it may attempt to load the URL later, for instance, after the user restarts the browser.
Sure. I'm not speaking about preserving the full history stack in the URL, just storing state. Apologies in advance if my explanation for what I mean is something you already understand.
This can be as simple as having a single checkbox with a checked/unchecked state.
when you load the webpage, the javascript can pull in the url parameters with URLSearchParams (https://developer.mozilla.org/en-US/docs/Web/API/URLSearchPa...). If the url parameter you set is set to 'on' then the checkbox, which is by default unchecked, can be set to on.
You have your checkbox:
<input type="checkbox" id="check">
And then you have your javascript:
const check = document.getElementById('check');
// get state of checkbox from URL parameter
check.checked = new URLSearchParams(location.search).get('state') === 'on';
// add event listener to call history api to alter the URL state.
check.onchange = () => { history.replaceState(null, '', check.checked ? '?state=on' : '?state=off'); };
The history.replaceState() replaces the URL in your history with the one including the URL parameter, so if a user were to bookmark it, it would store that and reload it when they revisit the webpage.
If I used history.pushState(), each time I clicked on the checkbox, a new item would be added to the stack. for a checkbox this is almost certainly a bad idea because your browser history is going to be polluted pretty quickly if you happen to click it multiple times.
pushState can be useful when it matches the user expectations, though, like if it is an SPA and the user clicks on an internal link to another section of the site, they'd expect to be able to go back to the previous page, even though we're still on the same actual html page.
So you would not be preserving the entire history stack. You can sort of do this by encoding state changes into another url parameter, but the behavior isn't entirely consistent between browsers. It also does require, as far as I know, an explicit action from the user for it to actually affect their navigation. So a website couldn't just add 1000 entries to the user's history on load without some explicit interaction on the web page.
Once the user interacts, though, it does seem like it opens up a lot of opportunity to abuse it, intentionally or not. You can asynchronously push thousands of entries into the browser history without blocking interactivity of the site. you can even continue to push state to the URL from other inputs while doing so.
It should be opt-in per website, per feature, because IMO it can be quite useful in some cases. Like clicking back on a slide-show bringing you to the overview page, instead of only going back one slide
> clicking back on a slide-show bringing you to the overview page
That behavior is expected in exactly one case (assuming slides, not the whole presentation, are modeled as a page each): If I navigated to that specific slide from the overview.
In any other scenario, this behavior amounts to breaking my back button, and I'll probably never visit the site again if I have that choice.
Opt in features are a great way to increase user frustration and confusion. See the whole new geolocation API they had to make for browsers since people would perma-deny it reflexively and then complain that geolocation features weren't working.
That's a good point, though I'm not familiar with the (changes to the) geolocation API you mention. Do you have any recommendations for reading up on that development?
> I feel like anything loaded from a third party domain
Unfortunately this would break some libraries for SPA management that people sometimes load from CDNs (external, or under their control but not obviously & unambiguously 1st-party by hostname) instead of the main app/page location. You could argue that this is bad design IMO, and I'd agree, but it is common design so enforcing such a limit will cause enough uproar to not be worth any browser's hassle.
I do like that they follow up this warning with “We encourage site owners to thoroughly review …” - too many site/app owners moan that they don't have control over what their dependencies do as if loading someone else's code absolves them from responsibility for what it does. Making it clear from the outset that this is the site's problem, not the user's, or something that the UA is doing wrong, or the indexer is judging unfairly, is worth the extra wordage.
facebook.com does this as a first party site, shit sites trying to squeeze eyeball time from visitors should be put on Google's malware sites list, but apparently those are the best sites nowadays... :/
There are valid use cases however the issue is rooted in lacking browser APIs.
For instance,
- if you want to do statistics tracking (how many hits your site gets and user journeys)
- You have a widget/iframe system that needs to teardown when the SPA page is navigated away
- etc
The browser does not have a;
globalThis.history.addEventListener('navigate')
So you must monkey patch the history API. It's impractical from a distribution standpoint to embed this code in the page bundle as it's often managed externally and has its own release schedule.
> - if you want to do statistics tracking (how many hits your site gets and user journeys)
You can do all of that server-side and much more reliably at that. The only reason to do any of this tracking client-side is advertisers trusting fake number go up more than sales numbers.