Focus Management with the Navigation API
By default, when a navigation is intercepted, after the promise returned by the handler() has resolved the browser will focus the first element that uses the autofocus attribute, if there is one. If not, the browser will focus the <body> element. That’s the right behaviour the majority of the time, but in certain scenarios a different approach needs to be taken. A dialog is a clear example: when the dialog is closed, focus should move back to the link or button that opened it. Keyboard users should be able to continue from where they left off rather that having to tab from the top of the page.
To opt out of the default behaviour, set focusReset to "manual":
event.intercept({
focusReset: "manual",
async handler() {
renderRouteSomehow(event.destination.url);
},
});
Click one of the below images and then close the dialog via your keyboard to see this in action:
When you adopt client-side routing, you lose out on some built-in browser behaviours. In an MPA, when a user traverses back or forward through their history, the browser uses the back/forward cache to restore focus to whichever element was focused when the user was previously on that page. As the Navigation API explainer documents, it is possible to reimplement that functionality, although it does sound rather involved.
See this article for a more general discussion of focus management in single page applications.


