Consider this scenario: you are on index.html and click a link to detail.html which gets intercepted to load the necessary data via fetch. While the data of detail.html is still being fetched (due to a slow network, for example) you click the home icon which links to index.html(again via interception).
The Navigation API reports three entries:
index.html
detail.html (interrupted)
index.html
While this list is Technically Correct™, UX-wise the visitor never saw the detail page, so they perceive it as going from index to index.
This problem becomes visible when throwing View Transitions in the mix, in which I use the current and target URL to determine which type of transition to run.
The current URL can be determined via window.location.href or navigation.currentEntry
The destination URL can be determined via event.destination.url.
In the scenario I described earlier, where the navigation to detail.html gets interrupted, determining the value for the currentURL using navigation.currentEntry is unreliable. Upon clicking the home icon in the scenario, the reported currentURL is detail.html, even though that navigation was never finished. As a result, the View Transition that will eventually run is a slide-backwards animation with the index.html page, as the code has determined it is going from detail.html to index.html.
Visually this is incorrect: the new index.html page should not slide in in this case, as the user was still seeing the old index.html page.
Proposed Solution(s)
Give authors control to defer a commit
Part of the original explainer included a section on how to defer a commit, but one had to commit it manually. This has not made it into the final specification, for reasons unknown to me.
Building upon that idea, it would look something like this, which would only commit an entry after a successful navigation.
Expose a lastSuccessfulEntry property on the Navigation object. The Navigation API updates this value automatically after a successful navigation has finished.
The advantage to using Navigation.lastSuccessfulEntry is that it is something that can easily be polfyilled:
// Get initial value on page load
navigation.lastSuccessfulEntry = navigation.currentEntry;
// Update after a successful navigation
navigation.addEventListener('navigatesuccess', e => {
navigation.lastSuccessfulEntry = e.currentTarget.currentEntry;
});
I’m also interested in the commit the url change after navigation. I thought it was agreed it was crucial for routers and that such feature would be added
Problem Statement
Demo page: https://view-transitions.netlify.app/stack-navigator/mpa-with-navigation-api/
Consider this scenario: you are on
index.html
and click a link todetail.html
which gets intercepted to load the necessary data via fetch. While the data ofdetail.html
is still being fetched (due to a slow network, for example) you click the home icon which links toindex.html
(again via interception).The Navigation API reports three entries:
index.html
detail.html
(interrupted)index.html
While this list is Technically Correct™, UX-wise the visitor never saw the detail page, so they perceive it as going from index to index.
This problem becomes visible when throwing View Transitions in the mix, in which I use the current and target URL to determine which type of transition to run.
window.location.href
ornavigation.currentEntry
event.destination.url
.Something like this:
In the scenario I described earlier, where the navigation to
detail.html
gets interrupted, determining the value for thecurrentURL
usingnavigation.currentEntry
is unreliable. Upon clicking the home icon in the scenario, the reportedcurrentURL
isdetail.html
, even though that navigation was never finished. As a result, the View Transition that will eventually run is a slide-backwards animation with theindex.html
page, as the code has determined it is going fromdetail.html
toindex.html
.Visually this is incorrect: the new
index.html
page should not slide in in this case, as the user was still seeing the oldindex.html
page.Proposed Solution(s)
Give authors control to defer a commit
Part of the original explainer included a section on how to defer a commit, but one had to commit it manually. This has not made it into the final specification, for reasons unknown to me.
Building upon that idea, it would look something like this, which would only commit an entry after a successful navigation.
Keep track of of
Navigation.lastSuccessfulEntry
Expose a
lastSuccessfulEntry
property on theNavigation
object. The Navigation API updates this value automatically after a successful navigation has finished.The advantage to using
Navigation.lastSuccessfulEntry
is that it is something that can easily be polfyilled:I have used this approach in https://view-transitions.netlify.app/stack-navigator/mpa-with-navigation-api/
Because it is that easy to polyfill, you could argue that in that case it’s not necessary to build this into the Navigation API, though.