This is a (multiple allowed):
There is a page on my app that can't figure on page history (the browser #! part), because it cannot function without information from previous page. So, I navigated to this page using { pushState: false }. That worked, except that when I hit the back button, two pages are back, instead of one.
To better illustrate:
This is the initial pag (/)e:

When user click on the first button, it navigates to this page (/customers/):

Ok. Now the next step is tricky, because I can't push the url for the next route, because it depends on some state on my vuex (so, user can't copy/paste the next url). The way I found for this to work is to navigate using this.$f7.router.navigate("/customers/categories/", { pushState: false });, so, I get this page, without the url push (notice the address bar):

Wondeful! User can't copy the url of this page.
BUT, if I hit the back button, it goes to this page (you actually can see two pages being animated out of history):

I tried pushState: false, history: true, but that generate the incorrect address (the one I want to hide) for the 3rd screen.
When a page is not pushed to the state, I want it to appear, without pushing the url to location.hash, but keep history.
The page is not pushed to state (correct), the history is pushed (correct), the back button pulls 2 histories from state (incorrect).
It would be a LOT helpful for a whole section on F7Router, with some real uses:
1) How to navigate forward without changing browser address bar, when user can't paste the url (internal urls) (this case).
2) How to clear N histories from current route (imagine a wizard with 5 pages and a "finish" button at the end: this button would have to clear the entire page history 5 pages behind (so it would be back where we started).
3) How to prevent routes and redirect the user to a login popup (I can contribute with this one, although my solution is kinda hacky: https://gist.github.com/JCKodel/ed916760adef5d8d702f94611013e9cc)
Perhaps other users can ask or contribute for more router cases (for both F7 vanilla and vue).
Notice:
Using this.$f7.router.navigate("/customers/categories/", { pushState: true, history: false }); almost worked:
1) There's an animation bug (the home appears, then the correct page pops in, animated).
2) It work fine, if you use the back link (but if you use the browser back button (or android back button)), things are broken just like my first post.
Would setting a route for step2 and then doing a check on component mount/load for state and then redirecting to step 1 if its missing. Get around the issue for now?
- How to navigate forward without changing browser address bar, when user can't paste the url (internal urls) (this case).
With what you have already did by setting pushState: false for this route. But the main issue here is yes, if user will click the native browser back button, then it can't prevent browser history from being changed to previous URL, not much really possible to do with that. So i can better recommend to actually change url with normal pushState flow. And in this route, e.g. async route, you can check (if user shared the link), if required date is in your vuex store then load it, otherwise do reject().
- How to clear N histories from current route (imagine a wizard with 5 pages and a "finish" button at the end: this button would have to clear the entire page history 5 pages behind (so it would be back where we started).
With pushState not possible, as it is not possible to modify browser history. Without pushState, you can call pass reloadAll: true or clearPreviousHistory: true to .navigate() params and it will clear all previous pages from history
- How to prevent routes and redirect the user to a login popup
What is wrong with your solution? Looks good and logical to me :)
In v3 there is a new preRoute route parameter that basically adds async route functionallity to any route, and allow to stack these pre route functions. e.g.
function checkAuth(to, from, resolve, reject) {
if (userIsAutorized) {
resolve();
} else {
// do something to auth user
reject();
}
}
function checkPermission(to, from, resolve, reject) {
if (userHasPermission) resolve();
else reject();
}
routes = [
{
path: '/about/',
component: AboutPage,
},
{
path: '/profile/',
component: ProfilePage,
preRoute: checkAuth,
},
{
path: '/messages/',
component: MessagesPage,
// if both checkAuth and checkPermission will be resolved then route will be loaded
preRoute: [checkAuth, checkPermission],
},
]
@nolimits4web
Just knew about the new feature preRoute; really helpful and was looking for that.
Can we have similar feature preExist; this will help us to reject the exit if user have some edited fields and want confirm user for ignore changes..
Thank you for the answers.
@nolimits4web
about your example https://github.com/framework7io/framework7/issues/2446#issuecomment-401375564
According to documentation
beforeEnter: function (routeTo, routeFrom, resolve, reject) or
beforeEnter: [checkAuth, checkPermission],
seems you have rename it from preRoute to beforeEnter
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.
This issue has been automatically closed due to inactivity. If this issue is still actual, please, create the new one.
Most helpful comment
With what you have already did by setting
pushState: falsefor this route. But the main issue here is yes, if user will click the native browser back button, then it can't prevent browser history from being changed to previous URL, not much really possible to do with that. So i can better recommend to actually change url with normal pushState flow. And in this route, e.g.asyncroute, you can check (if user shared the link), if required date is in your vuex store then load it, otherwise doreject().With
pushStatenot possible, as it is not possible to modify browser history. Without pushState, you can call passreloadAll: trueorclearPreviousHistory: trueto.navigate()params and it will clear all previous pages from historyWhat is wrong with your solution? Looks good and logical to me :)
In v3 there is a new
preRouteroute parameter that basically addsasyncroute functionallity to any route, and allow to stack these pre route functions. e.g.