ionic-framework icon indicating copy to clipboard operation
ionic-framework copied to clipboard

bug: switching between shared tab urls does not preserve individual tab stack history

Open philmmoore opened this issue 2 years ago • 19 comments

Prerequisites

Ionic Framework Version

  • [ ] v4.x
  • [ ] v5.x
  • [X] v6.x
  • [ ] Nightly

Current Behavior

Within an application we may want to switch from one tab to another to see what information is on the other tab.

If I am on Tab 2 and navigate to a child route /tabs/tab2/view then tap on Tab 3 from the tab bar and again navigate to a child route within Tab 3 /tabs/tab3/view I am able to switch between Tab 1, 2 and 3 and the correct views are displayed

https://user-images.githubusercontent.com/2862059/165835293-5bd102df-7a38-4299-9fb3-0e2ccd9c4760.mp4

If I then navigate to Tab 3 and press back (uses IonBackButton) the view will correctly navigate back.

https://user-images.githubusercontent.com/2862059/165835551-55f2a5ed-ca56-4db2-99e3-5701bcda3680.mp4

But If I then go to Tab 2 from the tab bar you'll notice that on Tab 2 I no longer have a back button and can no longer get back to the preview view.

https://user-images.githubusercontent.com/2862059/165835966-39c29bf5-8208-48c6-9b3f-6c67257533de.mp4

Tabbing to Tab 1 or 3 does not help. Only tapping the tab on the tab bar quickly does anything but you then have to navigate away and back again.

https://user-images.githubusercontent.com/2862059/165836231-299b5b3f-8df6-4bbe-af66-fd70d960e2f3.mp4

Expected Behavior

I would expect to be able to navigate to child routes within tabs and each nav stack work independently so that I could travel X number of levels deep in Tab 2 then Tab into Tab 3 and again travel X number of levels deep. If I then wanted to get back to the root view for the tab I would either tab the tab bar quickly to 'popToRoot' or use the IonBackButton within each child view to make my way back up.

Steps to Reproduce

Repro steps should be pretty self explanatory based on the videos shown in the current behaviour.

https://user-images.githubusercontent.com/2862059/165837728-88402e4e-624f-49fe-b26a-f6b56048c1f3.mp4

  1. Tab to Tab 2
  2. Tap Go to view
  3. Tab to Tab 3
  4. Tap go to view
  5. Tab back to Tab 2 and press the back button
  6. Tab back to Tab 3 and you'll see the back button has gone
  7. Double tap Tab 3 (notice there's a slight flicker in the video above)
  8. Tab back to Tab 2 and then straight back to Tab 3
  9. Notice that you're now back on the root view for the tab

Code Reproduction URL

https://github.com/philmmoore/ionic-tabs-bug

Ionic Info

Ionic:

Ionic CLI : 6.18.1 (/Users/philmmoore/.nvm/versions/node/v16.11.1/lib/node_modules/@ionic/cli) Ionic Framework : @ionic/vue 6.1.3

Capacitor:

Capacitor CLI : 3.5.0 @capacitor/android : not installed @capacitor/core : 3.5.0 @capacitor/ios : 3.5.0

Utility:

cordova-res (update available: 0.15.4) : 0.15.3 native-run : 1.5.0

System:

NodeJS : v16.11.1 (/Users/philmmoore/.nvm/versions/node/v16.11.1/bin/node) npm : 8.0.0 OS : macOS Big Sur

Additional Information

No response

philmmoore avatar Apr 28 '22 20:04 philmmoore

Thanks for the issue. Does this dev build help at all? I am fixing a similar issue in https://github.com/ionic-team/ionic-framework/pull/25206.

npm install @ionic/[email protected] @ionic/[email protected]

liamdebeasi avatar Apr 28 '22 22:04 liamdebeasi

Hey @liamdebeasi still able to follow repro steps and it fails.

Happy to try any other dev builds when they're ready 👍

https://user-images.githubusercontent.com/2862059/165866428-a8e122b9-4bd5-429d-8c6f-a78a1aeaafa7.mp4

philmmoore avatar Apr 29 '22 00:04 philmmoore

https://user-images.githubusercontent.com/38668796/165935299-d3b6b474-5bc3-4a0e-9de8-a79f3da33aa2.mp4

ionic ios router-link change menu bug

iam used vue and version 6.1.3

some problem

productdevbook avatar Apr 29 '22 12:04 productdevbook

@productdevbook That behavior appears to be unrelated to the issue being discussed in this thread. Please open a separate issue.

liamdebeasi avatar Apr 29 '22 12:04 liamdebeasi

Hey @liamdebeasi still able to follow repro steps and it fails.

Happy to try any other dev builds when they're ready 👍

Simulator.Screen.Recording.-.iPhone.12.Pro.-.2022-04-29.at.01.03.02.mp4

Thanks for testing! The issue appears to be that when going back to Tab 3 for the second time, the browser is wiping the history. The reason for this is when you go back to Tab 2 (you should be on the Tab 2 child page) and press the ion-back-button, we call router.go() to go back to the previous instance of Tab 2. When you tap Tab 3, we push a new /tabs/tab3/view route which causes the browser to clear its routing history.


The big limiting factor here is that the browser history wants linear navigation. Mobile tabs are non-linear by nature as each tab is its individual stack.

For example, consider the following flow:

/tabs/tab2 --> /tabs/tab2/view --> /tabs/tab3 (tap the Tab 3 button) --> /tabs/tab3/view --> /tabs/tab2/view (tapping the Tab 2 button again).

If you press the ion-back-button you should go back to /tabs/tab2. This is what happens right now.

However, if you press the hardware back button multiple times on an Android device, you should be taken backwards through the following flow:

/tabs/tab3/view --> /tabs/tab3 --> /tabs/tab2. Note that going from /tabs/tab3 brings you to /tabs/tab2 not /tabs/tab2/view. The reason for this is we already popped /tabs/tab2/view off the Tab 2 stack. This does not happen due to the issue I noted above.


Both the issue you noted and the hardware back button issue stem from how we push new routes when switching between tabs. I have a few ideas for how we can solve this, so I am going to talk with the team and see which option is best.

liamdebeasi avatar Apr 29 '22 13:04 liamdebeasi

The ion-back-button issue reproduces in Ionic Vue, but the hardware back button issue reproduces across Ionic Angular, Ionic React, and Ionic Vue.

I tested this using the Ionic React Conference App and the Ionic Angular Conference App.

liamdebeasi avatar Apr 29 '22 13:04 liamdebeasi

Hey @liamdebeasi thanks for the explanation, undestood!

Pleased we've got it logged as I've had to rework my app to use ion-nav and pushing views onto its own stack but I'd of course prefer to be able to use the router.

philmmoore avatar Apr 29 '22 14:04 philmmoore

Quick update: We need to fix https://github.com/ionic-team/ionic-framework/issues/25255 and https://github.com/ionic-team/ionic-framework/issues/24594 before we can fix this issue.

We have a fix in place for https://github.com/ionic-team/ionic-framework/issues/25255, and it is currently being reviewed by the team.

liamdebeasi avatar May 11 '22 12:05 liamdebeasi

Hey @liamdebeasi do you have an idea of when this issue might get worked on again, it's really preventing me from creating tabbed applications with nested routes.

Cheers

philmmoore avatar Jul 21 '22 22:07 philmmoore

@liamdebeasi Hello, may I know will this be fixed? Thanks.

mannok avatar Aug 25 '22 04:08 mannok

We do not provide time estimates of when these issues will be resolved. However, when we do have an update we will post it here.

liamdebeasi avatar Aug 25 '22 12:08 liamdebeasi

Hi, Is this issue still being addressed? We also have issues with back button showing up and not working in tabs when doing nested navigation in multiple tabs and switching between them.

If i understand this issue right, for now its impossible to make tabbed apps with the vue-router?

torgnywalin avatar Jan 10 '23 10:01 torgnywalin

Pleased we've got it logged as I've had to rework my app to use ion-nav and pushing views onto its own stack but I'd of course prefer to be able to use the router.

@philmmoore do you have any information and/or code that you could share regarding the approach you used to get around this issue using ion-nav? Thanks.

mmoore99 avatar Jun 26 '23 16:06 mmoore99

@liamdebeasi until, when and if, this issue gets resolved there should be a warning in the Vue section of the documentation that using tabs with child views is broken. The inability to have child views in tabs severely restricts the ability to use ionic/vue for many types of apps and developers should be aware of this before going down the road, following the documentation and then running into a big roadblock after a lot of time and effort is expended. The documentation (see quote below) should not be showing this approach as an example of how to architect an application when it is not possible.

This is obviously not a trivial bug since it has been open for quite some time. At the very least please make developers aware of this so they don't waste a lot of valuable time.

Instead, we recommend having routes in each tab that reference the same component. This is a practice done in popular apps like Spotify. For example, you can access an album or podcast from the "Home", "Search", and "Your Library" tabs. When accessing the album or podcast, users stay within that tab. The app does this by creating routes per tab and sharing a common component in the codebase.

mmoore99 avatar Jun 26 '23 16:06 mmoore99

@liamdebeasi until, when and if, this issue gets resolved there should be a warning in the Vue section of the documentation that using tabs with child views is broken. The inability to have child views in tabs severely restricts the ability to use ionic/vue for many types of apps and developers should be aware of this before going down the road, following the documentation and then running into a big roadblock after a lot of time and effort is expended. The documentation (see quote below) should not be showing this approach as an example of how to architect an application when it is not possible.

This is obviously not a trivial bug since it has been open for quite some time. At the very least please make developers aware of this so they don't waste a lot of valuable time.

Instead, we recommend having routes in each tab that reference the same component. This is a practice done in popular apps like Spotify. For example, you can access an album or podcast from the "Home", "Search", and "Your Library" tabs. When accessing the album or podcast, users stay within that tab. The app does this by creating routes per tab and sharing a common component in the codebase.

I completely agree with you. It definitely must be mentioned in the documentation that child routes in tabs are broken. We have an app that is built on tabs with many child routes in each tab. Hence, ionic vue tabs are broken for use with child routes, we are now unable to continue developing using vue ionic. We have already been developing the app for some time before we stuck on this issue

rmnkk avatar Aug 16 '23 14:08 rmnkk

Has anyone managed to find a workaround for this issue?

Andr9651 avatar Jan 09 '24 07:01 Andr9651

In fact, I think moving to new framework is the best option, like me. Because of this issue, I moved to react native. It is so much better intern of experience and performance.

I don't think a framework which take years to fix this fundamental bug deserve its user to stay and wait.

mannok avatar Jan 09 '24 23:01 mannok

I think I've managed to find a simple workaround. If the ion-back-button component works as expected with routing, then why dont I just override the hardware back button to do the same? So I looked into the source for ion-back-button and found that it used a function called handleNavigateBack from a supposed "ionRouter" injected from the key "navManager". It didn't match any IonRouter definition I've seen so I looked it up. It turns out, if I understand this comment correctly, that this issue has already been solved, it's just not been fully integrated.

This is what I ended up doing to fix the issue: (Keep in mind that I don't really know what I'm doing and my project is still rather small so, unforeseen issues might arise. It also only fixes the issue for the android hardware back button, as it doesn't seem to be possible to modify the navigation history in web or PWA scenarios)

I just added this to my tabs page, which based on the hardware back button documentation, should stop the default back button behavior and instead do the same thing as clicking on a ion-back-button component.

import type { createIonRouter } from '@ionic/vue-router/dist/types/router.d.ts';
const ionicNavManager = inject('navManager') as ReturnType<typeof createIonRouter>;

useBackButton(1, () => {
  if (ionicNavManager === undefined || ionicNavManager === null) {
    return;
  }

  ionicNavManager.handleNavigateBack();
});

@liamdebeasi Do you see any obvious issues with this workaround and is there any reason this isn't the default behavior?

Andr9651 avatar Jan 10 '24 07:01 Andr9651

Do you see any obvious issues with this workaround and is there any reason this isn't the default behavior?

The issue is not limited to using the hardware back button as it reproduces when tapping tab buttons too which is why we have not implemented that as a solution. We have some design work for this internally to resolve the issue, and I'll definitely follow up here when we have something that is testable.

liamdebeasi avatar Jan 10 '24 14:01 liamdebeasi