iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Navigation Patterns

Ionic uses your framework’s router (Angular Router, React Router, Vue Router) under the hood, with IonRouterOutlet handling native-feeling stack transitions and back gestures.

Angular + React routing with IonRouterOutlet

EXAMPLE
// === Angular (Ionic + Angular Router) ===

// app-routing.module.ts
import { NgModule } from '@angular/core';
import { PreloadAllModules, RouterModule, Routes } from '@angular/router';

const routes: Routes = [
    { path: '',           redirectTo: 'home', pathMatch: 'full' },
    { path: 'home',       loadComponent: () => import('./home/home.page').then(m => m.HomePage) },
    { path: 'post/:id',   loadComponent: () => import('./post/post.page').then(m => m.PostPage) },
    { path: 'tabs',
      loadComponent: () => import('./tabs/tabs.page').then(m => m.TabsPage),
      children: [
          { path: '',         redirectTo: 'feed', pathMatch: 'full' },
          { path: 'feed',     loadComponent: () => import('./feed/feed.page').then(m => m.FeedPage) },
          { path: 'profile',  loadComponent: () => import('./profile/profile.page').then(m => m.ProfilePage) },
      ],
    },
    { path: 'login',      loadComponent: () => import('./login/login.page').then(m => m.LoginPage) },
    { path: '**',         loadComponent: () => import('./not-found/not-found.page').then(m => m.NotFoundPage) },
];

@NgModule({
    imports: [RouterModule.forRoot(routes, { preloadingStrategy: PreloadAllModules })],
    exports: [RouterModule],
})
export class AppRoutingModule {}

// app.component.html
// <ion-app>
//   <ion-router-outlet></ion-router-outlet>
// </ion-app>

// Inside a page — navigate programmatically
import { NavController } from '@ionic/angular';
@Component({ /* … */ })
export class HomePage {
    constructor(private nav: NavController) {}

    open(id: string) {
        this.nav.navigateForward(`/post/${id}`, { animated: true });
    }
    back() {
        this.nav.navigateBack('/home');
    }
}

// Read route params
import { ActivatedRoute } from '@angular/router';
constructor(private route: ActivatedRoute) {
    this.id = this.route.snapshot.paramMap.get('id')!;
}

// === React (Ionic React) ===

import { IonReactRouter } from '@ionic/react-router';
import { IonApp, IonRouterOutlet, IonTabs, IonTabBar, IonTabButton } from '@ionic/react';
import { Route, Redirect } from 'react-router-dom';

export default function App() {
    return (
        <IonApp>
            <IonReactRouter>
                <IonRouterOutlet>
                    <Route exact path="/home"      component={HomePage} />
                    <Route       path="/post/:id"  component={PostPage} />
                    <Route       path="/tabs"      component={TabsPage} />
                    <Route exact path="/"          render={() => <Redirect to="/home" />} />
                </IonRouterOutlet>
            </IonReactRouter>
        </IonApp>
    );
}

// useHistory / useParams
import { useHistory, useParams } from 'react-router-dom';
function PostPage() {
    const history = useHistory();
    const { id }  = useParams<{ id: string }>();
    return <IonButton onClick={() => history.push('/home')}>Back</IonButton>;
}

// === Tabs (Angular) ===
// tabs.page.html
// <ion-tabs>
//   <ion-tab-bar slot="bottom">
//       <ion-tab-button tab="feed"    href="/tabs/feed">    <ion-icon name="home"/></ion-tab-button>
//       <ion-tab-button tab="profile" href="/tabs/profile"><ion-icon name="person"/></ion-tab-button>
//   </ion-tab-bar>
// </ion-tabs>

// === Common gotchas ===
//   • Use ion-router-outlet at the ROOT, not just <router-outlet> — keeps native gestures
//   • Tabs need IonTabs around IonTabBar AND IonRouterOutlet — both required
//   • Back-button behaviour — set defaultHref on ion-back-button to handle deep links

Why it matters

IonRouterOutlet is what gives Ionic apps native-feeling page transitions and swipe-back gestures. A vanilla <router-outlet> won’t cut it — the framework-specific wrapper is mandatory.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
// Push a new page
nav.push(ProfilePage);
// Or with React Router
history.push('/profile/42');
Try it Yourself »

Discussion

Loading…