Ion-back-button with with non-consuming routes


I would appreciate a comment on my situation below regarding how the back-button consumes route segments.

I am fully aware of the problems of the back button not showing if there is nothing to go back to or if there is no defaultHref. This is not my problem.

It seems that when the route has non-segment-consuming components the back button will navigate backwards one step too far.

-In my routing table have a Home-section that is wrapped with a shell component before lazy loading the actual route, say page A.

const routes = [{ path: 'home', component: ShellComponent, children: [...] }]

-From page A, I navigate to another page in another page, say B.
-Then I navigate further to page C by clicking something on page B. Page B and C are outside the Home section.
-When at page C I click on the back-button I will be returned to page A - not page B.

By experimenting, I have found out that if I remove the shell component, the navigation behaves as expected.

Is this different behavior with the shell by design or am I doing something wrong? How can I avoid this and make the behavior “normal”?

The shell component is essential to me, as it is here I decide whether to show a mobile or a desktop layout. Removing it would require a re-thinking of the architecture/navigation strategy of the whole app.

Any thoughts?


Do you have a sample we could look at? Typically, we don’t suggest using shell components and keeping your navigation as flat/simple as possible

Thanks for the quick reply. Barring fires to put out, I’ll try to get back to you with a sample-project tomorrow.

Do you know the reasoning behind wrapper components being discouraged? As far as I understand it is an architectural option provided by design in Angular.

If not using a shell-component, what would be the recommended best practice on how one would manage the differentiation between web-desktop and web-mobile - with the same “neutral” url?


Hi Mike,

Please find below a clone-link to a Github public project which demonstrates the problem I am facing. The readme -file is pasted below for your convenience.

I appreciate your time and would be very grateful for some advice on how to handle this.

Shell-component demo

The purpose of this project is to demonstrate how using a non-segment-consuming wrapper component seems to throw off the ion navigation stack and cause unexpected behavior with the ion-back-button.

Background and problem

I am working with ionic web app and need to differentiate the navigation between web-desktop and web-mobile, while having a neutral url that can be shared to other users regardless whether the recipients are using web or mobile.

Steps to verify

  1. Run the app.

  2. Navigate from root to Feature A. Notice that the back button is missing.

  3. Continue navigation to the list page. Notice back button appearing. (now there is something in the history to go back to)

  4. Navigate from the list to the detail page inside Feature B. Notice the missing back button. (history has been cleared?) Notice that the browser’s back button works correctly.

Isolating the cause

In the router-modules of FeatureA and FeatureB, comment out the lines which reference/apply the shell component (where the the diffrenentiation between web-mobile vs web-desktop would be done.)

The back button works as expected


Is this behavior by design? If so, then what would be the recommended approach to solve my problem?

So this is by design, you should not be embedding ion-router-outlets inside other ion-router-outlets.

Since ion-router-outlet creates it’s own navigation stack, when you go from the root to feature-a (which has it’s own ion-router-outlet), you are essentially creating a new navigation stack, so there is no context of the outer one.

Why do you need to differentiate between desktop and mobile? IMO, that creates a disconnect between what is basically the same “platform”. Simply put… it seems sus.

We do not have an app yet, only web. Our product idea is not mature enough to warrant the investment. Until we get our product/marketing/all else -strategy sorted out, I want to provide at least a differentiated user experience for web-on-a-mobile and web-on-a-desktop users as our primary marketing channel would be FB, which people use on a mobile.

I write this before I test it, but do you think, I could circumvent the problem by using the Angular framework’s router-outlet on “lower-levels” i.e feature modules?

Don’t know for sure, but you still not have the back button as that is tied to Ionic’s own internal router logic.

The best option would be to use the router module as the “shell” for this.

so in my app, I have a route that loads up a users music library.

    path: 'library',
    loadChildren: () =>
      import('./pages/library/library.module').then((m) => m.LibraryModule),

This loads the library module which itself is an empty module for other routes.

const routes: Routes = [
    path: '/',
    redirectTo: 'library/albums',
    pathMatch: 'full',
    path: 'albums',
    loadChildren: () =>
      import('./albums/albums.module').then((m) => m.AlbumsPageModule),
    path: 'albums/:id',
    loadChildren: () =>
      import('./album/album.module').then((m) => m.AlbumPageModule),

This way, the routes all render at the top level outlet, but I can control the sub routes that get rendered.


I am not sure I am getting this correct.

Are you saying that as ion-routeroutlet’s can/should not be nested, there can/should be only one ion-router-outlet per application? To me it seems that this works quite fine - until a wrapper component is introduced. Why would one want to restrict on purpose this architectural choice?

What am I misunderstanding?


You are correct, you should not be doing is nesting ion-router-outlet inside another ion-router-outlet.

This is because when ion-router-outlet is rendered, it creates it’s own sub-navigation,

Think of it like this:

  • you have one root ion-router-outlet, it creates it’s own navigation instance.
  • you have a component with renders another ion-router-outlet
    • there is now new ion-router-outlet/navigation instance

You should not be doing this.

Why would we restrict this?

  1. Angular’s own routing solution have some quirks with how nested outlets work
  2. To support ionic’s stack navigation (ion-tabs), there needs to be a stricter setup for how things are established, as routing can be very complex to manage.

Again…don’t nest ion-router-outlets in your app. Ever.

Okay. Nested outlets are bad and therefore I cannot use nested wrapper components.

So, as I need to differentiate the layout and navigation (bottom tabs vs side-menu) for web-mobile, and web-desktop, what would be the recommended way to do this with Ionic?

Am I missing something obvious here?