As organizations build cross-platform mobile applications with faster development cycles, recruiters must identify Ionic professionals who can deliver high-quality apps using web technologies. Ionic enables developers to build iOS, Android, and web applications from a single codebase using HTML, CSS, JavaScript, and frameworks like Angular, React, or Vue.
This resource, "100+ Ionic Interview Questions and Answers," is tailored for recruiters to simplify the evaluation process. It covers a wide range of topics—from Ionic fundamentals to advanced mobile development concepts, including UI components, native integrations, and performance optimization.
Whether you're hiring Ionic Developers, Mobile App Developers, or Hybrid App Engineers, this guide enables you to assess a candidate’s:
For a streamlined assessment process, consider platforms like WeCP, which allow you to:
Save time, enhance your hiring process, and confidently hire Ionic developers who can build fast, scalable, and cross-platform mobile applications from day one.
Ionic is an open-source UI framework designed for building cross-platform mobile, web, and desktop applications using standard web technologies—HTML, CSS, and JavaScript—along with frameworks like Angular, React, or Vue.
The core problem Ionic solves is:
Ionic solves this by allowing developers to write a single codebase that runs across:
Ionic provides:
Thus, Ionic dramatically reduces development effort, improves maintainability, and speeds up deployment across platforms.
Ionic and Cordova are related but serve different purposes.
FeatureIonicCordovaPurposeUI frameworkNative runtime bridgeProvidesComponents, layouts, UXNative plugins, app packagingRuns where?Browser + mobileMobile onlyReplacementNoneBeing replaced by Capacitor
Cordova is not required for Ionic anymore because Capacitor is now the official native runtime.
An Ionic application follows a three-layer architecture:
This layer is built using HTML, CSS, JavaScript, and Ionic Web Components.
Includes:
These components render with platform-specific styling (iOS, Android).
This is powered by Angular/React/Vue.
Includes:
Angular (most common) contributes:
This uses Capacitor plugins to access native features:
This layer contains:
When packaged for Android/iOS, the app runs inside a native WebView container but still behaves like a real native app.
Ionic components are pre-built UI elements created using Web Components and SVG/CSS-based UI patterns. They are reusable building blocks for creating mobile-friendly user interfaces.
Examples:
ion-header, ion-toolbar, ion-titleion-button, ion-iconion-list, ion-item, ion-avatarion-tabs, ion-side-menuion-grid for responsive layoutsThese components allow developers to create polished applications without manually coding complex UI from scratch.
The Ionic CLI (Command Line Interface) is installed globally using npm.
npm install -g @ionic/cli
After installation, verify using:
ionic -v
This confirms that Ionic CLI is correctly installed and ready to use.
Capacitor is the official native runtime for Ionic applications. It provides a modern WebView wrapper and a JavaScript bridge to access native device features.
Capacitor solves major limitations of Cordova by introducing:
Capacitor is now the primary native tool recommended by Ionic.
Capacitor is a modern replacement for Cordova.
FeatureCapacitorCordovaPhilosophyWeb-firstNative-firstPlugin systemModern, consistent, easierLegacy, inconsistentProject structureSyncs with a real Xcode/Android Studio projectCordova controls native projectsWeb supportFull PWA supportNo web supportLive reloadBuilt-inHard to configureNative codeDirect editing allowedChanges overwritten
Cordova is still available but considered "legacy".
Pages in Ionic are view components that represent screens in the mobile app (Home, Login, Profile, etc.).
A typical Ionic page contains:
.html).ts).scss)Using Ionic CLI:
ionic generate page home
This creates a folder:
home/
home.page.html
home.page.ts
home.page.scss
home.page.spec.ts
Pages are integrated into the app through Angular routing:
{ path: 'home', component: HomePage }
Pages help structure the app into modular, navigable UI screens.
Ionic uses Angular as the application framework that handles:
Ionic provides UI components, but Angular provides the application logic scaffolding.
Ionic + Angular benefits:
Thus, Angular is the backbone that powers app logic, while Ionic handles UI.
A typical Ionic Angular app has this folder structure:
project/
│
├── src/
│ ├── app/
│ │ ├── app-routing.module.ts
│ │ ├── app.module.ts
│ │ └── pages/modules/services
│ ├── assets/
│ ├── environments/
│ ├── global.scss
│ ├── index.html
│ └── theme/
│
├── capacitor.config.ts
├── package.json
└── angular.json
1. /src/app/
app.module.ts bootstraps the Ionic app.app-routing.module.ts defines navigation routes.2. /src/assets/
3. /src/theme/
4. /src/environments/
5. /src/global.scss
6. /android and /ios
npx cap add android.This structure ensures maintainability, scalability, and modular development.
ion-content is one of the most essential Ionic components. It acts as the main scrollable container for the body of a page. Everything displayed inside the page (text, lists, forms, buttons, cards) is usually placed inside ion-content.
It provides:
ion-refresher) and infinite scroll (ion-infinite-scroll).It automatically adjusts the content to fit within iOS safe areas such as:
ion-content supports backgrounds:
When used with lists, ion-content helps ensure efficient rendering on mobile devices through virtual scrolling.
<ion-content>
<h1>Welcome</h1>
<p>This is scrollable content.</p>
</ion-content>
Overall, ion-content is the core visual container for screen-level UI in Ionic apps.
ion-grid is Ionic’s responsive layout system based on a 12-column grid, similar to Bootstrap but optimized for mobile.
It allows developers to create flexible, responsive UI layouts that automatically adjust for:
xs, sm, md, lg, xl).<ion-grid>
<ion-row>
<ion-col size="6">Left</ion-col>
<ion-col size="6">Right</ion-col>
</ion-row>
</ion-grid>
ion-grid is used for structuring complex UIs, aligning components, and building adaptive layouts.
Ionic apps historically used ion-nav, but now Ionic Angular primarily uses Angular Router wrapped by ion-router.
In summary:
Navigation in Ionic Angular uses Angular Router, not ion-nav.
app-routing.module.tsconst routes: Routes = [
{ path: 'home', component: HomePage },
{ path: 'about', component: AboutPage }
];
Using Angular’s Router service:
this.router.navigate(['/about']);
3. Navigate using template links
<ion-button routerLink="/about">Go to About</ion-button>
4. Back navigation
this.navController.back();
5. Passing data
this.router.navigate(['/details', itemId]);
Or via navigation extras:
this.router.navigate(['details'], {
queryParams: { id: 5 }
});
Modern Ionic apps rely on Angular Router for predictable, scalable navigation patterns.
The Ionic CLI (Command Line Interface) is a powerful development tool used to:
ionic start myApp tabs
2. Run apps
ionic serve
Starts a dev server with live reload.
ionic generate page login
ionic generate service auth
4. Build production bundles
ionic build
5. Integrate Capacitor
ionic capacitor add android
ionic capacitor run ios
Supports deploy to web, Android, or iOS.
CLI simplifies debugging on real hardware.
In short, Ionic CLI streamlines the entire development lifecycle.
To create a new Ionic project, follow these steps:
npm install -g @ionic/cli
2. Create the project
ionic start myApp tabs
You can choose templates:
blanktabssidemenulisttutorialCLI will ask:
cd myApp
5. Run the application
ionic serve
This launches your app with hot reload.
Creating a new project through the CLI provides a fully scaffolded Ionic and Angular environment ready for development.
Live Reload is a feature that automatically refreshes the app whenever code changes are made.
.html, .ts, .scss).ionic serve
Live Reload on Android/iOS device:
ionic capacitor run android -l --external
It is one of the most productive features in the Ionic ecosystem.
Ionic Storage is a key–value data storage engine used to store persistent data in an Ionic application.
It supports multiple storage engines:
Import module:
imports: [
IonicStorageModule.forRoot()
]
Usage in code:
await this.storage.set('token', 'abc123');
const token = await this.storage.get('token');
Ionic Storage is the recommended solution for small-to-medium persistent data needs.
Ionic forms are built on top of Angular Forms Module, offering both:
<form #f="ngForm">
<ion-input name="email" ngModel></ion-input>
</form>
In TypeScript:
form = this.fb.group({
email: ['', [Validators.required, Validators.email]],
password: ['', Validators.required]
});
In HTML:
<form [formGroup]="form">
<ion-input formControlName="email"></ion-input>
<ion-input formControlName="password"></ion-input>
</form>
ion-input, ion-select, ion-checkbox, ion-datetimeIonic forms combine Angular’s powerful form engine with mobile-optimized components.
Ionic lifecycle events are hooks that allow you to run code at specific moments when a page becomes active or inactive.
These events are triggered by Ionic’s navigation system, not Angular’s component lifecycle.
EventDescriptionionViewWillEnterFired just before the page becomes active. Use to load data.ionViewDidEnterFired when page is fully visible. Good for starting animations.ionViewWillLeaveFired before navigating away. Use to pause listeners.ionViewDidLeaveFired after leaving page. Cleanup resources.
ionViewWillEnter() {
console.log('Page is about to be shown');
}
ionViewDidEnter() {
console.log('Page fully visible');
}
These events complement Angular’s lifecycle (ngOnInit, ngOnDestroy) for a more mobile-oriented behavior.
ion-modal is a powerful Ionic component used to display content on top of the current page, similar to a popup or dialog. Modals are commonly used in mobile apps to present:
Creating a modal in Ionic Angular involves using the ModalController.
import { ModalController } from '@ionic/angular';
Step 2: Inject ModalController into constructor
constructor(private modalCtrl: ModalController) {}
Step 3: Create and present the modal
async openModal() {
const modal = await this.modalCtrl.create({
component: MyModalPage, // Component to load inside modal
componentProps: {
userId: 10 // Pass data to modal
}
});
await modal.present();
}
Step 4: Dismiss modal from inside
this.modalCtrl.dismiss({
result: 'success'
});
Step 5: Get data back from modal
const { data } = await modal.onWillDismiss();
console.log(data);
Modals in Ionic are highly flexible and can load full-screen pages, custom UI layouts, or small dialog-style screens.
ion-alert is a lightweight, pre-styled dialog component used to show:
Alerts are simpler than modals and usually contain:
const alert = await this.alertCtrl.create({
header: 'Warning',
message: 'Are you sure you want to delete?',
buttons: ['Cancel', 'Yes']
});
await alert.present();
Use ion-alert when you need a simple, quick dialog rather than a full modal UI.
ion-list and ion-item are complementary but serve different purposes.
Example:
<ion-list>
<ion-item>Item 1</ion-item>
<ion-item>Item 2</ion-item>
</ion-list>
Example:
<ion-item>
<ion-label>Name</ion-label>
<ion-input></ion-input>
</ion-item>
ComponentPurposeion-listA container for grouping multiple list rowsion-itemA single interactive row inside a list
You almost always use ion-item inside ion-list.
ion-tabs is used to create tab-based navigation similar to many mobile apps (Instagram, WhatsApp bottom tabs).
Tabs allow users to switch between major sections of the app without losing the state of each tab.
<ion-tabs>
<ion-tab-bar slot="bottom">
<ion-tab-button tab="home">
<ion-icon name="home"></ion-icon>
<ion-label>Home</ion-label>
</ion-tab-button>
<ion-tab-button tab="settings">
<ion-icon name="settings"></ion-icon>
<ion-label>Settings</ion-label>
</ion-tab-button>
</ion-tab-bar>
</ion-tabs>
Each tab corresponds to a route:
const routes: Routes = [
{
path: 'tabs',
component: TabsPage,
children: [
{ path: 'home', loadChildren: () => import('./home/home.module').then(m => m.HomePageModule) },
{ path: 'settings', loadChildren: () => import('./settings/settings.module').then(m => m.SettingsPageModule) }
]
}
];
Tabs are ideal for organizing major app sections in a user-friendly manner.
Theming in Ionic refers to customizing the look and feel of the entire application using:
Located in:
src/theme/variables.scss
Defines:
Example:
:root {
--ion-color-primary: #3880ff;
--ion-color-secondary: #5260ff;
}
Ionic supports automatic or manual dark mode:
@media (prefers-color-scheme: dark) {
:root {
--ion-background-color: #000;
}
}
Each component can override theme variables.
ion-refresher allows users to pull down from the top of a page to refresh the content—similar to the refresh gesture in mobile apps like Gmail or Instagram.
<ion-content>
<ion-refresher (ionRefresh)="doRefresh($event)">
<ion-refresher-content></ion-refresher-content>
</ion-refresher>
</ion-content>
In TypeScript:
doRefresh(event) {
setTimeout(() => {
event.target.complete();
}, 1000);
}
It enhances mobile user experience significantly and provides a natural, expected gesture for refreshing data.
ion-infinite-scroll loads more data automatically when the user scrolls to the bottom of a list.
Perfect for:
<ion-content>
<ion-list>
<ion-item *ngFor="let item of items">{{ item }}</ion-item>
</ion-list>
<ion-infinite-scroll (ionInfinite)="loadMore($event)">
<ion-infinite-scroll-content></ion-infinite-scroll-content>
</ion-infinite-scroll>
</ion-content>
TypeScript:
loadMore(event) {
setTimeout(() => {
this.addMoreItems();
event.target.complete();
}, 1000);
}
Global styles allow you to apply CSS across the entire application.
Ionic provides two main files:
src/global.scssAdd global CSS rules, utility classes, and common styling.
Example:
.text-bold {
font-weight: 700;
}
src/theme/variables.scssOverride Ionic theme variables, colors, spacing, fonts.
Example:
:root {
--ion-font-family: 'Roboto';
}
Ionic's global styling system ensures consistent branding and design across all app screens.
ion-loading is a lightweight component used to show a spinner overlay while performing a background task such as:
It blocks user interaction temporarily and indicates progress.
const loading = await this.loadingCtrl.create({
message: 'Please wait...',
spinner: 'crescent'
});
await loading.present();
Dismiss it:
await loading.dismiss();
ion-loading improves UX by giving clear feedback that the system is busy.
Deploying an Ionic app to a physical device involves using Capacitor and the platform’s native tools (Android Studio or Xcode).
ionic build
This creates a production-ready web build in the www/ folder, which Capacitor uses.
npx cap sync
This command copies the latest web build into the native Android/iOS projects.
npx cap open android
This opens the project in Android Studio, where you can:
npx cap open ios
This opens the project in Xcode, where you can:
Once opened in Android Studio or Xcode, simply click:
Deployment uses the native toolchain because Ionic apps become native apps via Capacitor.
Testing in the browser is one of the easiest ways to verify UI and logic instantly.
ionic serveionic serve
This:
ionic build
Then serve via a local HTTP server.
Press Ctrl + Shift + M to simulate:
Use the console and network tab to verify:
Browser testing is fast and ideal for UI development before deploying to real devices.
ionic serve is a CLI command used to run the Ionic application in a development server.
ionic serve
ionic serve --port=8101)It significantly speeds up development since you don’t need to rebuild the app for every minor change.
config.xml is the central configuration file used in Cordova-based Ionic apps (before Capacitor became the default).
Example:
<preference name="Orientation" value="portrait" />
Defines paths for assets on both Android and iOS.
Defines which domains the app can access.
config.xml.Hybrid and native apps differ in development approach, technology, and performance characteristics.
Built with platform-specific languages:
Built using web technologies (HTML, CSS, JS) and wrapped inside a native container (WebView).
Frameworks:
FeatureNativeHybridPerformanceHighestModerate–HighCodebaseSeparate (iOS & Android)SingleDevelopment costHighLowUIPlatform-specificWeb-basedMaintenanceHarderEasier
Ionic apps fall into the hybrid category, but with modern WebView performance they feel almost native.
Ionic integrates with native device features using Capacitor, which serves as a bridge between JavaScript and native code.
import { Camera } from '@capacitor/camera';
const photo = await Camera.getPhoto({
quality: 90,
resultType: 'base64'
});
This makes Ionic apps capable of accessing nearly all native features like a fully native app.
Plugins are reusable modules that provide access to native device features.
These plugins allow JavaScript to interact with:
Provided by Capacitor:
Example:
npm install @capacitor/camera
Provided by third-party developers.
Written in Swift/Kotlin when custom functionality is needed.
npx cap sync)Plugins provide the key functionality that makes hybrid apps behave like real native apps.
A WebView is a native component used to run web content (HTML, CSS, JS) inside a mobile application.
In Ionic applications, the WebView acts as the container that displays the app UI, powered by the device’s browser engine.
Ionic apps are fundamentally web apps running inside a native shell, but with access to native features.
This is what makes Ionic a hybrid framework.
Debugging Ionic apps involves using browser tools and platform-specific debugging tools.
Use:
Steps:
ionic capacitor run android -l
Open Chrome and navigate:
chrome://inspect
You can:
Steps:
Use:
Add logging in native plugin files (Swift/Kotlin).
Building an installable app package requires Capacitor + native toolchain.
ionic build
Step 2: Sync with Capacitor
npx cap sync android
Step 3: Open in Android Studio
npx cap open android
Android Studio →
Build → Build Bundle(s) / APK(s) → Build APK
You get:
debug.apkrelease.apkionic build
Step 2: Sync
npx cap sync ios
Step 3: Open in Xcode
npx cap open ios
Xcode →
Product → Archive → Distribute App
You can upload to TestFlight or export an .ipa.
Ionic integrates with Angular using a layered architecture that combines:
Ionic provides a rich set of Web Components built using Stencil.js. These components (ion-button, ion-input, ion-header, etc.) render:
These components are framework-agnostic, but Ionic Angular wraps them in Angular modules.
Angular provides:
This layer is responsible for business logic, state management, services, and data flow.
Ionic provides Angular bindings:
IonicModuleIonicRouteStrategy (for route reuse)ion-router-outlet (extends Angular router-outlet with animations)ionViewDidEnter, etc.)This layer bridges Angular’s SPA model with Ionic’s mobile navigation patterns.
Ionic apps run inside a native shell using Capacitor, which provides:
LayerResponsibilityIonic UI ComponentsVisual UI + cross-platform lookAngular FrameworkApp logic + routing + DIIonic Angular BridgeGlue between Angular + Ionic navigationCapacitorNative device integration
This layered architecture creates a powerful hybrid framework combining the best of Angular and native mobile capabilities.
Capacitor treats each native platform as a first-class project, not a generated artifact like Cordova.
When you run:
npx cap add android
npx cap add ios
Capacitor creates real native projects that developers can open with:
These projects stay synchronized with web code using:
npx cap sync
Capacitor maintains a real-time bridge that connects:
The bridge is fast, modern, and promise-based.
Native functionality is packaged into plugins, which Capacitor manages by:
Developers can customize:
Unlike Cordova, Capacitor does not overwrite your changes.
Capacitor does not build APK/IPA itself—platform toolchains do:
Capacitor only supplies the WebView + bridge.
Capacitor plugins are modular pieces of code that enable Ionic apps to access native functionality.
Every plugin exposes a JS API like:
import { Camera } from '@capacitor/camera';
Camera.getPhoto();
These APIs return Promises, not callbacks.
Each plugin may implement native code in:
Capacitor automatically selects the correct implementation.
Defines:
If a device lacks a native API, plugins can provide web-based implementations.
Example: Camera fallback uses file input on browser.
Plugins register automatically with Capacitor using decorators or configuration entries.
Developers can create custom plugins when:
This flexibility makes Capacitor highly extensible and future-proof.
Authentication in Ionic can be implemented in several ways depending on your backend and requirements.
Most common approach:
Example:
localStorage.setItem('token', jwt);
Using providers like:
Use Capacitor plugins for deep linking and secure authentication flows.
Firebase provides:
Perfect for Ionic because Firebase supports WebView-based apps.
Protect pages using Angular’s CanActivate.
canActivate() {
return this.authService.isLoggedIn();
}
Implement refresh_token logic for long-lived sessions.
Authentication in Ionic mirrors web app authentication, with mobile-specific enhancements for token storage and deep linking.
Routing in Ionic Angular is based on Angular Router, whereas Ionic v3 used a stack-based navigation controller.
Example:
this.navCtrl.push('DetailsPage');
Uses Angular Router:
<ion-button routerLink="/details">Details</ion-button>
Extends Angular’s router-outlet with:
FeatureIonic v3Ionic AngularNavigationStack-basedURL-basedRouterCustomAngular RouterLazy LoadingDecoratorsStandard AngularDeep LinkingLimitedFull supportPWAsWeakStrong
Modern Ionic apps rely entirely on Angular routing for scalable navigation.
Lazy loading helps load pages only when needed, improving performance.
ionic generate module pages/home --routing
ionic generate page pages/home
This creates:
home/
home.module.ts
home-routing.module.ts
In home-routing.module.ts:
const routes: Routes = [
{ path: '', component: HomePage }
];
Step 3: Add the lazy-loaded route in app-routing
{
path: 'home',
loadChildren: () => import('./pages/home/home.module')
.then(m => m.HomePageModule)
}
Lazy loading is essential for real-world Ionic production apps.
IonSlides is a component built on top of Swiper.js, enabling swipeable content areas such as intro screens, galleries, or product carousels.
When ion-slides loads, it initializes a Swiper instance with configuration options such as:
<ion-slides [options]="slideOpts">
<ion-slide>Slide 1</ion-slide>
<ion-slide>Slide 2</ion-slide>
</ion-slides>
You can control slides via methods:
this.slides.slideNext();
this.slides.slidePrev();
this.slides.getActiveIndex();
Events like:
ionSlideDidChangeionSlideWillChangeallow tracking user movement.
Swiper provides:
Ionic wraps Swiper to match its design and animation system.
Performance optimization is essential for smooth mobile experience.
Loads pages only when needed.
Improves rendering for long lists.
Large DOM trees slow down WebView rendering.
ion-img for lazy loadingUse:
ChangeDetectionStrategy.OnPush
7. Production Build
ionic build --prod
This enables:
Heavy animations degrade FPS on low-end devices.
Custom Ionic themes are user-defined color schemes, typography, and styling variables applied across the entire app to match brand identity.
In variables.scss:
:root {
--ion-color-primary: #1a73e8;
--ion-color-secondary: #ff9900;
}
2. Creating New Color Palettes
.ion-color-gold {
--ion-color-base: #e7b500;
--ion-color-contrast: #fff;
}
3. Typography Customization
:root {
--ion-font-family: 'Roboto';
}
4. Dark Mode Themes
@media (prefers-color-scheme: dark) {
:root {
--ion-background-color: #000;
}
}
Ionic’s CSS variable system makes theming extremely flexible without complex CSS overrides.
Ionic handles responsiveness using a combination of:
A 12-column responsive grid system that adapts across:
Ionic provides utility classes for:
Example:
<div class="ion-padding ion-text-center"></div>
Components auto-adjust their styling based on:
Developers can add custom breakpoints in global.scss:
@media (min-width: 768px) {
.desktop-only {
display: block;
}
}
Allows side menu to automatically become sidebar on tablets:
<ion-split-pane contentId="main">
<ion-menu></ion-menu>
<div id="main"></div>
</ion-split-pane>
Using Ionic’s Platform service:
if (this.platform.is('tablet')) { ... }
Ionic’s responsive system ensures apps adapt effortlessly to:
Media queries and Ionic utilities both support responsive design, but they work differently and serve different purposes.
Media queries are CSS rules that apply styles based on device characteristics like:
Example:
@media (min-width: 768px) {
.desktop-layout {
display: flex;
}
}
Ionic utilities are pre-built CSS helper classes that simplify styling.
Example utility classes:
<div class="ion-padding ion-text-center"></div>
Common utilities include:
ion-margin, ion-padding)ion-text-center)ion-hide, ion-show-md)Ionic provides platform-aware classes:
.ion-hide-sm-down.ion-show-lg.ion-hide-md-upExample:
<div class="ion-hide-md-down">Shown on mobile only</div>
FeatureMedia QueriesIonic UtilitiesTypeCSS rulesHelper classesFlexibilityVery highModerateLearning curveHigherEasyUse CaseCustom layoutsQuick styling & responsiveness
Use both together for advanced responsive layouts in real-world apps.
A service in Angular is a singleton class designed to handle reusable logic such as:
Angular services follow the Dependency Injection (DI) model.
ionic generate service services/user
This creates:
@Injectable({
providedIn: 'root'
})
export class UserService {
getUser() { ... }
}
The providedIn: 'root' ensures it is a singleton shared across all pages.
Inject it into a page/component:
constructor(private userService: UserService) {}
ngOnInit() {
this.userService.getUser();
}
Services are the backbone of business logic in both Angular and Ionic apps.
Ionic Angular uses Angular’s built-in HttpClient module to make HTTP requests.
In app.module.ts:
import { HttpClientModule } from '@angular/common/http';
@NgModule({
imports: [HttpClientModule]
})
export class AppModule {}
Step 2: Inject HttpClient into a service
constructor(private http: HttpClient) {}
getUsers() {
return this.http.get('https://api.example.com/users');
}
POST Request
login(data) {
return this.http.post('https://api.example.com/login', data);
}
PUT / DELETE
updateUser(id, user) {
return this.http.put(`https://api.example.com/users/${id}`, user);
}
Step 4: Subscribe in Component
this.userService.getUsers().subscribe(response => {
console.log(response);
});
HttpClient is the most important tool for connecting Ionic apps to backend APIs.
Interceptors are Angular middleware that "intercept" HTTP requests and responses globally.
They are powerful for:
ionic generate interceptor token
Example: Add Authorization Token
intercept(req: HttpRequest<any>, next: HttpHandler) {
const token = localStorage.getItem('token');
const cloned = req.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return next.handle(cloned);
}
In app.module.ts:
providers: [
{
provide: HTTP_INTERCEPTORS,
useClass: TokenInterceptor,
multi: true
}
]
Ionic provides two main storage systems:
Supports:
Automatically chooses best engine available.
npm install @ionic/storage-angular
In app.module.ts:
imports: [
IonicStorageModule.forRoot()
]
Usage
await this.storage.set('token', 'abc123');
const token = await this.storage.get('token');
Lightweight but more secure than localStorage.
import { Preferences } from '@capacitor/preferences';
await Preferences.set({
key: 'user',
value: JSON.stringify({ name: 'John' })
});
const user = await Preferences.get({ key: 'user' });
FeatureIonic StorageCapacitor PreferencesData SizeLargeSmallStorage EnginesIndexedDB, SQLiteOS Key-Value StoreUse CaseOffline appsSimple settings
The Capacitor Camera API allows accessing the device camera or photo gallery.
npm install @capacitor/camera
npx cap sync
Step 2: Use Camera in Code
import { Camera, CameraResultType } from '@capacitor/camera';
async takePhoto() {
const image = await Camera.getPhoto({
quality: 90,
resultType: CameraResultType.Base64,
source: 'CAMERA'
});
this.photo = 'data:image/jpeg;base64,' + image.base64String;
}
'CAMERA' or 'PHOTOS'Android and iOS require camera permissions configured in:
AndroidManifest.xmlInfo.plistWebView is the native container that runs the Ionic app.
PlatformWebViewAndroidChromium WebViewiOSWKWebView
ion-virtual-scroll is a performance optimization technique for large lists.
It renders only the visible items on the screen, not the entire list.
Example:
If you have 10,000 items, maybe only 12–20 are rendered at once.
<ion-virtual-scroll [items]="users" approxItemHeight="50px">
<ion-item *virtualItem="let user">
{{ user.name }}
</ion-item>
</ion-virtual-scroll>
approxItemHeight)Push notifications in Ionic use Capacitor + Firebase Cloud Messaging (FCM).
npm install @capacitor/push-notifications
Step 2: Register for permissions
import { PushNotifications } from '@capacitor/push-notifications';
PushNotifications.requestPermissions().then(result => {
if (result.receive === 'granted') {
PushNotifications.register();
}
});
Step 3: Listen for notifications
PushNotifications.addListener('pushNotificationReceived', notification => {
console.log('Notification received:', notification);
});
Set up Firebase project and download config files:
google-services.json for AndroidGoogleService-Info.plist for iOSIonic provides a Gesture Controller for implementing custom touch interactions such as:
import { GestureController } from '@ionic/angular';
const gesture = this.gestureCtrl.create({
el: myElement,
gestureName: 'swipe-gesture',
onMove: ev => console.log('Moving', ev),
onEnd: ev => console.log('Ended', ev)
});
gesture.enable(true);
Gestures allow Ionic apps to feel interactive, fast, and truly mobile-native.
IonNav and Angular Router are two different navigation mechanisms in Ionic, but they serve different architectural styles.
IonNav mimics a native mobile navigation stack:
Example:
this.nav.push(DetailPage);
Angular Router is the official navigation system for Ionic Angular apps.
It uses URL-based routing, like any Angular SPA:
<ion-button routerLink="/details">Go</ion-button>
Ionic team officially recommends avoiding IonNav unless you have a special requirement.
State management handles how data flows across the entire app, especially when dealing with:
Depending on the app’s size, Ionic provides multiple strategies.
Services store state in memory:
@Injectable({ providedIn: 'root' })
export class AuthService {
isLoggedIn = false;
}
All components use the same instance (singleton).
Best for small apps.
user$ = new BehaviorSubject(null);
Every component can subscribe to updates.
These libraries implement Redux-style global store.
Used for enterprise apps with huge datasets.
Use:
Example:
await Storage.set({ key: 'user', value: JSON.stringify(user) });
Often used for:
App SizeState ManagementSmallAngular serviceMediumRxJS subjectsLargeNgRx / NGXS / AkitaOfflineStorage + caching
NgZone is Angular’s mechanism for managing change detection in asynchronous operations.
Hybrid apps can run outside Angular’s normal zone because native plugins (Camera, Geolocation, FileSystem) execute outside Angular's change detection.
For example, when calling Capacitor:
Camera.getPhoto().then(photo => {
this.image = photo; // Angular may NOT update UI automatically
});
Native code runs outside Angular’s zone, so Angular won’t detect variable changes.
constructor(private zone: NgZone) {}
Camera.getPhoto().then(photo => {
this.zone.run(() => {
this.image = photo;
});
});
Without NgZone, hybrid apps may show stale UI or fail to update data.
Ionic’s build process prepares your app for deployment on Android, iOS, or Web.
Angular compiles .ts → .js
Includes:
Output stored in:
/www
This folder contains:
This is the final "web app".
npx cap sync
Copies the /www build into:
android/app/src/main/assets/public/ios/App/public/Capacitor does not build the app itself; it hands off to the native toolchains.
Enables:
This makes mobile apps much faster.
Firebase is used for:
npm install firebase
In environment.ts:
export const environment = {
firebaseConfig: {
apiKey: "...",
authDomain: "...",
projectId: "...",
storageBucket: "...",
messagingSenderId: "...",
appId: "..."
}
};
Step 3: Initialize Firebase
import { initializeApp } from 'firebase/app';
const app = initializeApp(environment.firebaseConfig);
import { getAuth, signInWithEmailAndPassword } from 'firebase/auth';
Firestore
import { getFirestore, doc, setDoc } from 'firebase/firestore';
Cloud Storage
import { getStorage, uploadBytes } from 'firebase/storage';
Use:
npm install @capacitor/push-notifications
Then connect Firebase Cloud Messaging (FCM).
Deep linking allows users to open a specific screen in the app using a URL.
Example link:
myapp://product/123
Opens directly to product page.
Browser-style navigation:
/product/12
Used for PWAs and web-based navigation.
Allows:
npm install @capacitor/app
Listen for URL opens:
App.addListener('appUrlOpen', (event) => {
console.log(event.url);
});
Ionic has first-class support for Progressive Web Apps (PWAs).
A PWA is a web app that behaves like a native app.
Enable:
Ionic UI components scale to desktop, tablet, and mobile.
Allows installation on home screen.
Ionic is considered one of the best frameworks for PWAs.
Offline mode ensures the app works without internet.
Cache API responses locally.
Enable through Angular PWA package:
ng add @angular/pwa
They handle:
Firebase Firestore has built-in offline mode.
import { Network } from '@capacitor/network';
If API fails → store request → sync later.
App reads from cache first → updates when online.
Offline is essential for:
Because Ionic apps run in WebView, API keys can be exposed if not secured.
Do NOT store sensitive keys in the app.
Use a backend proxy like:
Ionic app → Backend → Third-party API
But remember: This is NOT fully secure for secret keys.
Encrypts data using OS keychain:
SecureStoragePlugin.set({ key: 'apikey', value: '123' });
Some APIs support “key restrictions”:
Use JavaScript obfuscation to make reverse engineering harder.
Ensure tokens cannot be used outside your app.
These three commands serve different purposes.
Runs the app in browser.
ionic serve
Used in early development stages.
Builds production-ready web assets.
ionic build
This outputs the app into the:
/www
folder.
Runs the app on Android/iOS devices or emulators.
Example:
ionic capacitor run android
-l --external)CommandPurposePlatformionic serveBrowser dev serverWeb onlyionic buildCreate web buildAll (Android, iOS, Web)ionic capacitor runRun on device with native supportAndroid / iOS
Environment files allow you to separate development, staging, and production configuration settings — such as API URLs, keys, and feature flags.
Ionic uses Angular’s environment system.
Inside src/environments/ you get:
environment.ts → Development
environment.prod.ts → Production
Example (environment.ts):
export const environment = {
production: false,
apiUrl: 'https://dev.example.com/api',
firebaseConfig: {...}
};
Example (environment.prod.ts):
export const environment = {
production: true,
apiUrl: 'https://api.example.com',
firebaseConfig: {...}
};
3. Using Environment Variables
import { environment } from '../environments/environment';
this.http.get(environment.apiUrl + '/users');
Angular will automatically use the correct environment based on the build command:
ionic serve
Uses environment.ts
ionic build --prod
Uses environment.prod.ts
ng generate environment staging
Then include in angular.json under fileReplacements.
Environment files are essential for scalable real-world Ionic applications.
Debugging Capacitor plugins involves debugging JavaScript, Android native code, and iOS native code, because plugins run on all three layers.
Use console.log() in the JS implementation:
console.log('Plugin input:', data);
Inspect using browser DevTools or device inspector.
npx cap open android
Use Logcat:
Log.d("MyPlugin", "Debug message");
npx cap open ios
Insert debug logs:
print("Plugin executed: \(value)")
Enable verbose logging:
window.Capacitor.Plugins.MyPlugin.echo({ val: "Hello" });
Check:
Plugins may have fallback web versions — use browser DevTools.
LayerToolJavaScriptConsole + DevToolsAndroidLogcat + breakpointsiOSXcode debuggerBridgeCapacitor logs
ion-skeleton-text is used to show placeholder loading animations while actual content is being fetched from the server.
It mimics:
This improves perceived performance and avoids blank white screens.
<ion-skeleton-text animated style="width: 60%"></ion-skeleton-text>
<ion-skeleton-text animated style="width: 90%"></ion-skeleton-text>
Skeleton UI improves user experience significantly in data-heavy Ionic apps.