Ionic Tabs

Migrating to the Upgraded Ionic Tabs Components



·

In this tutorial, we are going to be walking through how to migrate your existing Ionic 4 applications that use tabs to the new tabs components that were introduced in beta.15. We will go through a simple example of converting the old tabs components to the new ones, and we will also discuss the general ideas behind the changes.

It is uncommon to see breaking changes introduced throughout the beta period, but in this case, it seems to be something that has been highly sought after and will provide a lot of benefits. Although it will require changes to your application, the required changes are small and easy to make. I intend to go into quite a bit of depth in this article, but the actual changes required are just a few small tweaks to the template containing the tabs.

Tabs in Ionic 4

With the release of Ionic 4 and the move to Angular style navigation, we saw some changes introduced to the way tabs worked. This was mostly in the way that the tabs component would integrate with the Angular routing system.

As with all the other pages in our application, we have to define routes for each of the tabs we want to display. Tabs are a bit of a special case because each tab has its own <ion-router-outlet> (its own navigation view) instead of using the single main <ion-router-outlet>. This means that each route for a specific tab needs to be tied to a specific <ion-router-outlet> through naming those outlets and specifying the matching outlet in the route for that tab using the outlet property.

This looks something like this:

const routes: Routes = [
    { 
        path: 'tabs', 
        component: HomePage,
        children: [
            {
                path: 'location',
                outlet: 'location',
                component: LocationPage
            },
            {
                path: 'camp',
                outlet: 'camp',
                component: CampDetailsPage
            },
            {
                path: 'me',
                outlet: 'me',
                component: MyDetailsPage
            }
        ]
    },
    {
        path: '',
        redirectTo: '/tabs/(location:location)'        
    }
];

If you would like to learn more about the general approach to creating a tabs layout in Ionic 4, then I would recommend reading: Creating a Tabs Layout with Angular Routing and Ionic 4.

I wanted to provide a bit of a recap of how the new tabs work, but I also want to highlight that this is not changing. You can keep the routes you have defined for your tabs layout exactly the same with the new tabs components.

Updating the Tabs Components

What is changing is the way we add the tabs components to our templates. The general idea behind these changes is to remove the tight integration between the tabs component and the underlying navigation system.

Previously, Ionic just provided a simple tabs component that would handle all the “magic” and display the tabs for you. Now, Ionic is just providing a more generic component that we can hook into whatever navigation system it is that we are using. The end result is a little bit more code, but a lot more flexibility. Tabs are now just this generic component that we can use however we see fit (e.g. you aren’t strictly limited to using tab buttons for a tabbed navigation interface).

A template using the old (pre-beta.15) tabs would look something like this:

<ion-tabs>
  <ion-tab label="Location" icon="navigate" href="/tabs/(location:location)">
    <ion-router-outlet name="location"></ion-router-outlet>
  </ion-tab>
  <ion-tab label="My Details" icon="person" href="/tabs/(me:me)">
    <ion-router-outlet name="me"></ion-router-outlet>
  </ion-tab>
  <ion-tab label="Camp Details" icon="bookmarks" href="/tabs/(camp:camp)">
    <ion-router-outlet name="camp"></ion-router-outlet>
  </ion-tab>
</ion-tabs>

This is actually an example from one of the applications in my book. Now, let’s take a look at what the template looks like after it has been upgraded to the new tabs:

<ion-tabs>

  <!-- Tabs -->
  <ion-tab tab="location">
    <ion-router-outlet name="location"></ion-router-outlet>
  </ion-tab>

  <ion-tab tab="me">
    <ion-router-outlet name="me"></ion-router-outlet>
  </ion-tab>

  <ion-tab tab="camp">
    <ion-router-outlet name="camp"></ion-router-outlet>
  </ion-tab>

  <!-- Tab Buttons -->
  <ion-tab-bar slot="bottom">

    <ion-tab-button tab="location" href="/tabs/(location:location)">
      <ion-icon name="navigate"></ion-icon>
      <ion-label>Location</ion-label>
    </ion-tab-button>

    <ion-tab-button tab="me" href="/tabs/(me:me)">
      <ion-icon name="person"></ion-icon>
      <ion-label>My Details</ion-label>
    </ion-tab-button>

    <ion-tab-button tab="camp" href="/tabs/(camp:camp)">
      <ion-icon name="bookmarks"></ion-icon>
      <ion-label>Camp Details</ion-label>
    </ion-tab-button>

  </ion-tab-bar>

</ion-tabs>

There is a bit more code now, but the general concept is still largely the same. The key difference here is that we have now separated the tab buttons out from the tabs themselves. We tie a specific <ion-tab-button> to a specific <ion-tab> by adding the tab attribute to both of them and giving them the same name.

All of the routing remains the same, we just attach the href to the associated tab button for a tab (again, instead of having it tied directly to the tab itself).

Summary

For some people, this change might not make much of a difference, but it does make tabs significantly more flexible:

  • You can now use <ion-tab-bar> and <ion-tab-button> independently of a tabbed navigation interface
  • You have more flexibility in determining what the tab buttons look like. You can supply whatever you like inside of <ion-tab-button> and since the elements you add will not be inside of a Shadow DOM you can style them directly with CSS.
  • Since the tabs component is now more generic, it can be more easily integrated with other frameworks/navigation systems

What to watch next...