See the Pen by Ionic (@ionic) on CodePen.

As a user navigates throughout your app, Ionic is able to keep track of their navigation history. By knowing their history, transitions between views correctly enter and exit using the platform’s transition style. An additional benefit to Ionic’s navigation system is its ability to manage multiple histories. For example, each tab can have it’s own navigation history stack.

Ionic uses the AngularUI Router module so app interfaces can be organized into various “states”. Like Angular’s core $route service, URLs can be used to control the views. However, the AngularUI Router provides a more powerful state manager in that states are bound to named, nested, and parallel views, allowing more than one template to be rendered on the same page. Additionally, each state is not required to be bound to a URL, and data can be pushed to each state which allows much flexibility.

The ionNavView directive is used to render templates in your application. Each template is part of a state. States are usually mapped to a url, and are defined programatically using angular-ui-router (see their docs, and remember to replace ui-view with ion-nav-view in examples).


In this example, we will create a navigation view that contains our different states for the app.

To do this, in our markup we use ionNavView top level directive. To display a header bar we use the ionNavBar directive that updates as we navigate through the navigation stack.

Next, we need to setup our states that will be rendered.

var app = angular.module('myApp', ['ionic']);
app.config(function($stateProvider) {
  .state('index', {
    url: '/',
    templateUrl: 'home.html'
  .state('music', {
    url: '/music',
    templateUrl: 'music.html'

Then on app start, $stateProvider will look at the url, see if it matches the index state, and then try to load home.html into the <ion-nav-view>.

Pages are loaded by the URLs given. One simple way to create templates in Angular is to put them directly into your HTML file and use the <script type="text/ng-template"> syntax. So here is one way to put home.html into our app:

<script id="home" type="text/ng-template">
  <!-- The title of the ion-view will be shown on the navbar -->
  <ion-view view-title="Home">
    <ion-content ng-controller="HomeCtrl">
      <!-- The content of the page -->
      <a href="#/music">Go to music page!</a>

This is good to do because the template will be cached for very fast loading, instead of having to fetch them from the network.


By default, views are cached to improve performance. When a view is navigated away from, its element is left in the DOM, and its scope is disconnected from the $watch cycle. When navigating to a view that is already cached, its scope is then reconnected, and the existing element that was left in the DOM becomes the active view. This also allows for the scroll position of previous views to be maintained.

Caching can be disabled and enabled in multiple ways. By default, Ionic will cache a maximum of 10 views, and not only can this be configured, but apps can also explicitly state which views should and should not be cached.

Note that because we are caching these views, we aren’t destroying scopes. Instead, scopes are being disconnected from the watch cycle. Because scopes are not being destroyed and recreated, controllers are not loading again on a subsequent viewing. If the app/controller needs to know when a view has entered or has left, then view events emitted from the ionView scope, such as $ionicView.enter, may be useful.

By default, when navigating back in the history, the “forward” views are removed from the cache. If you navigate forward to the same view again, it’ll create a new DOM element and controller instance. Basically, any forward views are reset each time. This can be configured using the $ionicConfigProvider:


Disable cache globally

The $ionicConfigProvider can be used to set the maximum allowable views which can be cached, but this can also be use to disable all caching by setting it to 0.


Disable cache within state provider

$stateProvider.state('myState', {
   cache: false,
   url : '/myUrl',
   templateUrl : 'my-template.html'

Disable cache with an attribute

<ion-view cache-view="false" view-title="My Title!">

AngularUI Router

Please visit AngularUI Router’s docs for more info. Below is a great video by the AngularUI Router team that may help to explain how it all works:

Note: We do not recommend using resolve of AngularUI Router. The recommended approach is to execute any logic needed before beginning the state transition.


Attr Type Details

A view name. The name should be unique amongst the other views in the same state. You can have views of the same name that live in different states. For more information, see ui-router's ui-view documentation.