Ionic 2 - global NavBar for the app

UPDATE:

Just like @mhartington says:

There is no way to create a global ion-navbar, as this is done on purpose. The point of having a navbar defined for each component is so that we can properly animate the titles, navbar background color (if you change them) and animate other properties needed.

And about creating a custom directive to avoid duplicating ion-navbar html code:

That will still creat errors with how angular2 content projection works. We have several issues that have been open when people try this and the best answer is to not do it.


NOT recommended solution:

In order to avoid duplicating so much code, you can create your own custom component for the navbar.

Create a navbar.html with this code:

<ion-navbar *navbar>
  <ion-title>MyApp</ion-title>
  <button  menuToggle="right" end>
    <ion-icon name="menu"></ion-icon>
  </button>

  <ion-buttons *ngIf="!hideCreateButton" end>
    <button (click)="createNew()"><ion-icon name="add"></ion-icon></button>
  </ion-buttons>
</ion-navbar>

And then in the navbar.ts:

import {Component, Input} from '@angular/core';
import {NavController} from 'ionic-angular';
import {CreateNewPage} from '../../pages/create-new/create-new';

@Component({
    selector: 'navbar',
    templateUrl: 'build/components/navbar/navbar.html',
    inputs: ['hideCreateButton']
})
export class CustomNavbar {

    public hideCreateButton: string;

    constructor(private nav: NavController) {
    }

    createNew(): void {
        this.nav.setRoot(CreateNewPage, {}, { animate: true, direction: 'forward' });
    }
}

By declaring the hideCreateButton as an input of the Component, you can decide in which pages show that button and in which ones should not be visible. So in this way, you can send information to tell the component how it should be, and customize it for each page.

So if you want to add the navbar in a page (without modifying the default template, so showing the create button) you just have to add the navbar element (binded to our custom component by us in the selector property):

<navbar></navbar>

<ion-content>
  ...
</ion-content>

And if you want to hide the create button (or modify you navbar like you want to) your page will look like this one:

<navbar [hideCreateButton]="hidebutton()"></navbar>

<ion-content>
   ...
</ion-content>

And remember that the hideButton() should be defined in your customPage.ts like this:

import {Component} from '@angular/core';
import {NavController} from 'ionic-angular';
import {FORM_DIRECTIVES, FormBuilder, ControlGroup, Validators, AbstractControl } from '@angular/common';

@Component({
  templateUrl: 'build/pages/create-new/create-new.html',
  directives: [FORM_DIRECTIVES]
})
export class CreateNewPage{

    private hideCreateButton: boolean = true;

    public hidebutton(): boolean {
        return this.hideCreateButton;
    }
}

For ionic 3+

What I did to solve this was simply use a custom component.

ionic generate component navbar
  • Add the relevant navbar html to your component template
  • Add any other functionality to your component .ts file
  • Modify your selector to something relevant, (if used command above it should just default to 'navbar'.
  • Also add the component to your app.module.ts declarations

Then in any of your page templates, simply use it as a custom element e.g

<navbar></navbar>
<ion-content padding>
   ...
</ion-content/>

I had a similar issue creating an Ionic 4+ app (@ionic/angular 4.6.2), I wanted to add a login button and some other global stuffs in the header.

You can achieve that in a quite simple way.

Just add a ion-header containing a ion-toolbar in your app.component.html as a global header, like this:

<ion-header class="page-header">
   <ion-toolbar id="main-toolbar">
      <ion-title>
        <ion-label>{{ pageTitle }}</ion-label>
      </ion-title>
      <!-- add here all the things you need in your header --> 
   </ion-toolbar>
</ion-header>
<ion-router-outlet id="content" main></ion-router-outlet>

The problem here is that the "global header" will overlay the content of any page if you do only that. So has a workaround just add an empty ion-header containing an empty ion-toolbar on top of all your pages before the content tag, as follow:

<ion-header>
  <ion-toolbar></ion-toolbar>
</ion-header>
<ion-content>
  <!-- your content here -->
</ion-content>

Doing that the "global header" will overlay the page header and the content will begin just after it.

Then you can manage all the code for your global header controls in your app.component.ts file.

I guess there could be some strange behaviour if the main header has a height greater than the "standard" toolbar height but with some nice CSS you should be able to fix it.

Furthermore, this workaround works fine with a side menu.

Hope it helps!