Build a Multilevel Accordion Menu in Ionic with Angular

by Didin J. on Jun 03, 2025 Build a Multilevel Accordion Menu in Ionic with Angular

Create a dynamic multilevel accordion menu in Ionic using Angular. Learn to build nested navigation from JSON data with collapsible components

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.

Build a Multilevel Accordion Menu in Ionic with Angular - demo app


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:

Thanks!