Next.js starter your AI actually understands. Ship internal tools in days not weeks. Pre-order $199 $499 → [Get it now]

How to create a sidebar in Angular

Creating a sidebar navigation is essential for most Angular applications, providing a consistent way to navigate between different sections. As the creator of CoreUI with over 10 years of Angular experience since 2014, I’ve built sidebar components for countless admin panels and enterprise applications. The most effective approach uses Angular standalone components with a service to manage sidebar state, CSS for styling and transitions, and Angular Router for navigation. This pattern provides a responsive, accessible sidebar that works across all screen sizes.

Create a sidebar component with toggle functionality using a shared service.

import { Component } from '@angular/core'
import { CommonModule } from '@angular/common'
import { RouterModule } from '@angular/router'

@Component({
  selector: 'app-sidebar',
  standalone: true,
  imports: [CommonModule, RouterModule],
  template: `
    <aside class="sidebar" [class.open]="isOpen">
      <nav>
        <ul>
          <li><a routerLink="/" routerLinkActive="active">Dashboard</a></li>
          <li><a routerLink="/users" routerLinkActive="active">Users</a></li>
          <li><a routerLink="/settings" routerLinkActive="active">Settings</a></li>
        </ul>
      </nav>
    </aside>
  `,
  styles: [`
    .sidebar {
      width: 250px;
      height: 100vh;
      background: #2c3e50;
      position: fixed;
      left: 0;
      top: 0;
      transition: transform 0.3s ease;
    }
    .sidebar.open {
      transform: translateX(0);
    }
    @media (max-width: 768px) {
      .sidebar {
        transform: translateX(-100%);
      }
    }
    nav ul {
      list-style: none;
      padding: 0;
      margin: 0;
    }
    nav li a {
      display: block;
      padding: 15px 20px;
      color: white;
      text-decoration: none;
    }
    nav li a:hover {
      background: #34495e;
    }
    nav li a.active {
      background: #3498db;
    }
  `]
})
export class SidebarComponent {
  isOpen = false
}

The sidebar uses routerLink for navigation and routerLinkActive to highlight the current route. The [class.open] binding toggles the open class. On mobile devices, the sidebar hides off-screen and slides in when opened. The CSS transitions provide smooth animations.

Creating a Sidebar Service

Manage sidebar state across components with a service.

import { Injectable } from '@angular/core'
import { BehaviorSubject } from 'rxjs'

@Injectable({
  providedIn: 'root'
})
export class SidebarService {
  private isOpenSubject = new BehaviorSubject<boolean>(false)
  isOpen$ = this.isOpenSubject.asObservable()

  toggle() {
    this.isOpenSubject.next(!this.isOpenSubject.value)
  }

  open() {
    this.isOpenSubject.next(true)
  }

  close() {
    this.isOpenSubject.next(false)
  }
}

The service uses a BehaviorSubject to store and broadcast sidebar state. The toggle() method switches between open and closed. The open() and close() methods provide explicit control. Components can subscribe to isOpen$ to react to state changes.

Connecting Sidebar to Service

Update the sidebar component to use the service.

import { Component, OnInit } from '@angular/core'
import { CommonModule } from '@angular/common'
import { RouterModule } from '@angular/router'
import { SidebarService } from './sidebar.service'

@Component({
  selector: 'app-sidebar',
  standalone: true,
  imports: [CommonModule, RouterModule],
  template: `
    <aside class="sidebar" [class.open]="isOpen$ | async">
      <nav>
        <ul>
          <li><a routerLink="/" routerLinkActive="active">Dashboard</a></li>
          <li><a routerLink="/users" routerLinkActive="active">Users</a></li>
          <li><a routerLink="/settings" routerLinkActive="active">Settings</a></li>
        </ul>
      </nav>
    </aside>
  `
})
export class SidebarComponent implements OnInit {
  isOpen$ = this.sidebarService.isOpen$

  constructor(private sidebarService: SidebarService) {}

  ngOnInit() {
    // Sidebar opens automatically on desktop
    if (window.innerWidth > 768) {
      this.sidebarService.open()
    }
  }
}

The component subscribes to the service’s isOpen$ observable using the async pipe. The ngOnInit automatically opens the sidebar on desktop screens. This pattern centralizes sidebar state management.

Creating a Toggle Button

Add a button in the header to toggle the sidebar.

import { Component } from '@angular/core'
import { SidebarService } from './sidebar.service'

@Component({
  selector: 'app-header',
  standalone: true,
  template: `
    <header>
      <button (click)="toggleSidebar()" class="menu-button">
      </button>
      <h1>My App</h1>
    </header>
  `,
  styles: [`
    header {
      height: 60px;
      background: #3498db;
      color: white;
      display: flex;
      align-items: center;
      padding: 0 20px;
      position: fixed;
      top: 0;
      left: 0;
      right: 0;
      z-index: 100;
    }
    .menu-button {
      background: none;
      border: none;
      color: white;
      font-size: 24px;
      cursor: pointer;
      margin-right: 20px;
    }
  `]
})
export class HeaderComponent {
  constructor(private sidebarService: SidebarService) {}

  toggleSidebar() {
    this.sidebarService.toggle()
  }
}

The header component injects the sidebar service and calls toggle() when the menu button is clicked. This allows users to open and close the sidebar from anywhere in the app.

Adding Nested Navigation

Create a sidebar with expandable menu sections.

import { Component } from '@angular/core'
import { CommonModule } from '@angular/common'
import { RouterModule } from '@angular/router'

interface MenuItem {
  label: string
  route?: string
  icon?: string
  children?: MenuItem[]
}

@Component({
  selector: 'app-sidebar-nested',
  standalone: true,
  imports: [CommonModule, RouterModule],
  template: `
    <aside class="sidebar">
      <nav>
        <ul>
          <li *ngFor="let item of menuItems">
            <a *ngIf="!item.children" [routerLink]="item.route" routerLinkActive="active">
              {{ item.label }}
            </a>
            <div *ngIf="item.children" class="menu-group">
              <button (click)="toggleGroup(item)" class="group-header">
                {{ item.label }}
              </button>
              <ul *ngIf="item.expanded" class="submenu">
                <li *ngFor="let child of item.children">
                  <a [routerLink]="child.route" routerLinkActive="active">
                    {{ child.label }}
                  </a>
                </li>
              </ul>
            </div>
          </li>
        </ul>
      </nav>
    </aside>
  `
})
export class SidebarNestedComponent {
  menuItems: MenuItem[] = [
    { label: 'Dashboard', route: '/' },
    {
      label: 'Users',
      children: [
        { label: 'All Users', route: '/users' },
        { label: 'Add User', route: '/users/new' },
        { label: 'User Roles', route: '/users/roles' }
      ]
    },
    { label: 'Settings', route: '/settings' }
  ]

  toggleGroup(item: MenuItem) {
    item.expanded = !item.expanded
  }
}

The menuItems array defines the navigation structure with optional children. The toggleGroup() method expands and collapses menu groups. This provides organized navigation for complex applications.

Best Practice Note

This is the same sidebar architecture we use in CoreUI Angular admin templates for responsive navigation. For production apps, add keyboard navigation support (Tab, Enter, Escape) for accessibility. Implement auto-close on mobile when navigating to a new route. Consider adding icons to menu items for better visual hierarchy. For complex applications with permissions, filter menu items based on user roles. Use CoreUI’s CSidebar component which provides a battle-tested sidebar with features like unfoldable navigation, backdrop overlays, and automatic responsive behavior out of the box.


Speed up your responsive apps and websites with fully-featured, ready-to-use open-source admin panel templates—free to use and built for efficiency.


About the Author

Subscribe to our newsletter
Get early information about new products, product updates and blog posts.
How to get element ID in JavaScript
How to get element ID in JavaScript

JavaScript printf equivalent
JavaScript printf equivalent

How to conditionally add attributes to React components
How to conditionally add attributes to React components

How to Conditionally Add a Property to an Object in JavaScript
How to Conditionally Add a Property to an Object in JavaScript

Answers by CoreUI Core Team