Creating organized and scalable navigation menus is essential for any mobile or web app. In this tutorial, you’ll learn how to build a multilevel accordion menu using the latest Ionic and Angular frameworks. This collapsible menu will display hierarchical JSON data and allow users to drill down through nested levels seamlessly.
This approach is particularly useful for apps that require structured menus like e-commerce categories, learning platforms, or admin dashboards.
What You’ll Build
A dynamic accordion menu that:
-
Displays nested levels from JSON data
-
Allows the expansion/collapse of each menu item
-
Uses clean, reusable components
Prerequisites
Make sure you have the Ionic CLI installed:
npm install -g @ionic/cli
Then, create a new Ionic Angular project:
ionic start multilevel-menu blank --type=angular
cd multilevel-menu
Add iOS and Android Platforms
npm install @capacitor/core @capacitor/cli
ionic cap add ios
ionic cap add android
Check the installed Angular and CLI versions and other information by typing this command.
ionic info
Ionic:
Ionic CLI : 7.2.1 (/opt/homebrew/lib/node_modules/@ionic/cli)
Ionic Framework : @ionic/angular 8.5.8
@angular-devkit/build-angular : 19.2.14
@angular-devkit/schematics : 19.2.14
@angular/cli : 19.2.14
@ionic/angular-toolkit : 12.2.0
Capacitor:
Capacitor CLI : 7.2.0
@capacitor/android : 7.2.0
@capacitor/core : 7.2.0
@capacitor/ios : 7.2.0
Utility:
cordova-res : not installed globally
native-run : 2.0.1
System:
NodeJS : v23.11.0 (/opt/homebrew/Cellar/node/23.11.0/bin/node)
npm : 10.9.2
OS : macOS Unknown
Add Nested Menu Data
Create a file named src/app/data/menu.ts
and define your multilevel menu:
export const MENU_DATA = [
{
title: 'Fruits',
children: [
{
title: 'Citrus',
children: [
{ title: 'Orange' },
{ title: 'Lemon' }
]
},
{
title: 'Berries',
children: [
{ title: 'Strawberry' },
{ title: 'Blueberry' }
]
}
]
},
{
title: 'Vegetables',
children: [
{ title: 'Carrot' },
{ title: 'Broccoli' }
]
}
];
Create the Accordion Menu Component
Generate a component to recursively render each level of the menu:
mkdir src/app/components
touch src/app/components/accordion-menu.component.ts
touch src/app/components/accordion-menu.component.html
touch src/app/components/accordion-menu.component.scss
In accordion-menu.component.ts:
import { CommonModule } from '@angular/common';
import { Component, Input } from '@angular/core';
import { IonList, IonItem, IonLabel, IonIcon } from "@ionic/angular/standalone";
@Component({
selector: 'app-accordion-menu',
templateUrl: './accordion-menu.component.html',
styleUrls: ['./accordion-menu.component.scss'],
imports: [CommonModule, IonIcon, IonLabel, IonItem, IonList],
})
export class AccordionMenuComponent {
@Input() menus: any[] = [];
activeIndices: Set<number> = new Set();
toggle(index: number) {
if (this.activeIndices.has(index)) {
this.activeIndices.delete(index);
} else {
this.activeIndices.add(index);
}
}
isActive(index: number): boolean {
return this.activeIndices.has(index);
}
}
In accordion-menu.component.html:
<ion-list>
<ng-container *ngFor="let menu of menus; let i = index">
<ion-item button (click)="toggle(i)">
<ion-label>{{ menu.title }}</ion-label>
<ion-icon slot="end" [name]="isActive(i) ? 'chevron-down' : 'chevron-forward'"></ion-icon>
</ion-item>
<div *ngIf="isActive(i)" class="submenu">
<app-accordion-menu *ngIf="menu.children" [menus]="menu.children"></app-accordion-menu>
</div>
</ng-container>
</ion-list>
In accordion-menu.component.scss:
.submenu {
margin-left: 20px;
}
Display the Menu in AppComponent
Update your src/app/app.component.ts
file to use the accordion menu:
import { Component } from '@angular/core';
import { MENU_DATA } from './data/menu';
import { AccordionMenuComponent } from './components/accordion-menu.component';
import { IonApp, IonHeader, IonToolbar, IonTitle, IonContent } from "@ionic/angular/standalone";
@Component({
selector: 'app-root',
templateUrl: 'app.component.html',
imports: [IonContent, IonTitle, IonToolbar, IonHeader, IonApp, AccordionMenuComponent],
})
export class AppComponent {
menus = MENU_DATA;
constructor() { }
}
Update your src/app/app.component.html:
<ion-app>
<ion-header>
<ion-toolbar>
<ion-title>
Multilevel Accordion Menu
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
<app-accordion-menu [menus]="menus"></app-accordion-menu>
</ion-content>
</ion-app>
Styling and Responsiveness
To create a polished and mobile-friendly multilevel accordion menu in Ionic, you'll want to enhance both the visual appearance and responsive behavior of the menu. Here's how to do it:
1. Indentation and Hierarchy Visualization
Use spacing and indentation to indicate hierarchy clearly. You can adjust .submenu
in accordion-menu.component.scss
:
.submenu {
margin-left: 16px;
border-left: 2px solid #ccc;
padding-left: 12px;
}
You can also use ion-padding-start
or Ionic Grid if you'd like it to be even more native-styled.
2. Icon Animation for Expand/Collapse
Instead of a static toggle icon, use a rotating icon to indicate the menu’s expansion state:
<ion-icon
slot="end"
[name]="isActive(i) ? 'chevron-down' : 'chevron-forward'"
[class.rotated]="isActive(i)">
</ion-icon>
Add to src/app/components/accordion-menu.component.scss:
ion-icon {
transition: transform 0.2s ease;
}
ion-icon.rotated {
transform: rotate(90deg);
}
3. Touch-Friendly Design
Ensure enough spacing for touch targets:
ion-item {
--min-height: 48px;
font-size: 16px;
}
This improves usability on smaller screens.
4. Dark Mode Support
Use Ionic’s theming features for dark mode support:
:host-context(body.dark) {
.submenu {
border-left: 2px solid #444;
}
}
5. Responsive Text Wrapping
To avoid overflow or clipping, make sure long menu titles wrap cleanly:
ion-label {
white-space: normal;
word-wrap: break-word;
}
6. Highlight Selected Items (Optional)
For a better UX, highlight active or selected items with color or background. In src/app/components/accordion-menu.component.ts:
selectedTitle: string | null = null;
select(title: string) {
this.selectedTitle = title;
}
isSelected(title: string): boolean {
return this.selectedTitle === title;
}
In src/app/components/accordion-menu.component.html:
<ion-item
button
[color]="isSelected(menu.title) ? 'primary' : ''"
(click)="toggle(i); select(menu.title)">
Final Thoughts
By layering in responsive spacing, transitions, dark mode compatibility, and touch-friendly elements, you create a menu that feels native, smooth, and user-friendly across all device types.
Run and Test Ionic Angular Multilevel Accordion Menu
There's nothing required to run and test this Ionic Angular Multilevel Accordion or collapsible menu. Just run in the browser:
ionic serve
Here's what the Ionic Angular Multilevel Accordion or collapsible menu looks like.
Conclusion
In this tutorial, you learned how to build a multilevel accordion menu in an Ionic application using Angular. We covered how to structure nested menu data, create a reusable AccordionMenuComponent
, implement expand/collapse logic, and style the menu for a clean and responsive UI.
This pattern is useful for apps with complex navigation needs, such as admin dashboards, content management systems, or e-commerce platforms. With Angular’s powerful binding and Ionic’s mobile-first components, the solution is both scalable and user-friendly.
By following this guide, you now have the foundation to:
-
Dynamically render nested menu items
-
Handle user interaction elegantly
-
Style the UI for responsiveness and mobile devices
-
Extend the component with routing, animations, or backend data
Feel free to expand this project further—add icons, integrate with Angular Router, or connect the menu structure to a backend for dynamic loading.
You can find the working source code on our GitHub.
We know that building beautifully designed Ionic apps from scratch can be frustrating and very time-consuming. Check Ionic 4 - Full Starter App and save development and design time. Android, iOS, and PWA, 100+ Screens and Components, the most complete and advanced Ionic Template.
That's just the basics. If you need more deep learning about Ionic, Angular, and TypeScript, you can take the following cheap course:
- IONIC 4 Design Hybrid Mobile Applications IOS & Android
- WordPress Rest API and Ionic 4 (Angular) App With Auth
- Mobile App from Development to Deployment - IONIC 4
- Ionic 4 Crash Course with Heartstone API & Angular
- Ionic 4 Mega Course: Build 10 Real World Apps
Thanks!