The problem is that getting those things right is 4x more difficult in a SPA app than a legacy, server rendered, app.
- No native back and forward button implementation. Now you must listen to an API and emulate the legacy behaviour.
- The concept of links, its also emulated via onClick events. This means that anything can be a link, so in many cases rows become links and their content is not really selectable as text. Legacy HTML has clear limitations for this not to happen.
- Same with buttons. There are no native buttons anymore. Anything can be a button, including any DIV with an event listener. Good luck tabbing through every DIV to get you to a button, that's also another difficult implementation.
Again, none of this is down to SPA frameworks (other than back/forward history APIs, lot of people break this unfortunately, though I've never understood how they manage to as I've never had this problem on projects I worked on). What often happens also is that people embed a bunch of iframes, and history within iframes can act very weirdly.
Links in Vue Router at least are just regular <a> tags. Yes the framework handles navigation when clicking these, but nothing prevents anyone from wrapping anything they want in an <a> tag even with no JS. You could make an entire table be clickable as a link if you wanted to, framework or not. "Legacy" HTML will render these just fine and browsers will make it a regular link, even though HTML validators will fail it.
Literally the first element anyone makes in frameworks will be a generic Button element that is simply a <button> with some styling. People abuse divs as buttons with or without frameworks because again, nothing prevents you from making any arbitrary element in your DOM have an onclick handler and act as a button. Tabbing through can even work with the correct ARIA attributes, and can even be broken on regular plain <button>s if abused hard enough.
I would seriously suggest people try out Vue or especially Svelte, they're about as simple as you can possibly get (especially Svelte 4) while giving you a lot of power and flexibility. I've worked with plenty of server-rendered apps in the past, and trust me, people would butcher things just as badly and easily there.
I wholehartly disagree - all of the mentioned problems are problems created by the developer. All these things work with the common SPA frameworks - developer just tend to forget what an anchor or a button is and use a span or div for it.
Having the proper tool and using the tool properly are two different things - and the web is a place where people forgot to do things the proper way.
- No native back and forward button implementation. Now you must listen to an API and emulate the legacy behaviour.
- The concept of links, its also emulated via onClick events. This means that anything can be a link, so in many cases rows become links and their content is not really selectable as text. Legacy HTML has clear limitations for this not to happen.
- Same with buttons. There are no native buttons anymore. Anything can be a button, including any DIV with an event listener. Good luck tabbing through every DIV to get you to a button, that's also another difficult implementation.