Mithril's router doesn't currently support use of a state object when routing. This is a problem for single page applications that want to implement correct browser back button behaviour.
For example, if I have two routes: A and B. The default route is A. I enter the site and do something to change the state of route A. Then I click a link through to route B. Now one of two things can happen:
I can click the browser back button. I expect to be taken back to route A with the preserved state.
Or, I can click a "home" link on route B which explicitly routes to A. I expect to be taken back to route A but with a fresh state.
Workarounds
One workaround is as follows: whenever state changes on route A, cache it on a global object. Then whenever route A is initialized, check the global for cached state and import it if it's present. Finally, when clicking the "home" link in route B, explicitly clear the cached state before routing back to A.
However, importantly, this does not actually produce identical behaviour to what using the history API properly would: if you start on route A, change state (which is cached), click a link to route B, click the "home" link to go back to route A, then clicked the browser back button twice (route A -> route B -> route A), the original cached state on route A will be lost.
Another workaround would be to serialize state in the URL... but this is far from elegant.
Possible solution
What if we allow another option to be passed in the m.route.set API. Whenever the state changes on route A, it can call the following:
This would set the given attrs object as the state when calling window.replaceState.
Then, when the back button is clicked, Mithril's window.onpopstate listener receives those attrs and can pass them into the component that is resolved from the new route (merged with the URL params). The component can then import the attrs into its state as appropriate.
I think this is important
The state object makes up a pretty important part of the history API and Mithril currently just ignores it completely. And I'd say I've put forth a pretty valid, common use-case — or at least one that should be common, if people are being responsible UX designers. Breaking the browser's back button and not providing a means for applications to fix it is pretty concerning.
Mithril's router doesn't currently support use of a state object when routing. This is a problem for single page applications that want to implement correct browser back button behaviour.
For example, if I have two routes: A and B. The default route is A. I enter the site and do something to change the state of route A. Then I click a link through to route B. Now one of two things can happen:
Workarounds
One workaround is as follows: whenever state changes on route A, cache it on a global object. Then whenever route A is initialized, check the global for cached state and import it if it's present. Finally, when clicking the "home" link in route B, explicitly clear the cached state before routing back to A.
However, importantly, this does not actually produce identical behaviour to what using the history API properly would: if you start on route A, change state (which is cached), click a link to route B, click the "home" link to go back to route A, then clicked the browser back button twice (route A -> route B -> route A), the original cached state on route A will be lost.
Another workaround would be to serialize state in the URL... but this is far from elegant.
Possible solution
What if we allow another option to be passed in the
m.route.set
API. Whenever the state changes on route A, it can call the following:This would set the given
attrs
object as the state when callingwindow.replaceState
.Then, when the back button is clicked, Mithril's
window.onpopstate
listener receives thoseattrs
and can pass them into the component that is resolved from the new route (merged with the URL params). The component can then import theattrs
into its state as appropriate.I think this is important
The state object makes up a pretty important part of the history API and Mithril currently just ignores it completely. And I'd say I've put forth a pretty valid, common use-case — or at least one that should be common, if people are being responsible UX designers. Breaking the browser's back button and not providing a means for applications to fix it is pretty concerning.