Native browser loading state
With the Navigation API — now shipped in all major browsers (Chromium since 2022, Safari and Firefox since) — you can show the native spinner + stop button for any asynchronous operation - all you need is a Promise.
function showLoading(promise) {
navigation.addEventListener(
'navigate',
(event) => {
event.intercept({
scroll: 'manual',
handler: () => promise,
})
},
{ once: true }
)
return navigation.navigate(location.href).finished
}
// show browser loading UI
showLoading(new Promise((r) => setTimeout(r, 1500)))
One caveat: navigation.navigate(location.href) pushes/replaces a history entry as a side effect — pass { history: 'replace' } if you don’t want a new entry.