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 navbar in Angular

Creating a navigation bar is fundamental for Angular applications, providing users with consistent access to different sections. As the creator of CoreUI with over 10 years of Angular experience since 2014, I’ve built navigation components for countless applications from simple websites to complex enterprise dashboards. The most effective approach uses Angular standalone components with RouterModule for navigation, responsive CSS for mobile layouts, and a service to manage mobile menu state. This pattern delivers a professional, accessible navbar that works across all devices.

Create a navbar component with routing and active link highlighting.

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

@Component({
  selector: 'app-navbar',
  standalone: true,
  imports: [CommonModule, RouterModule],
  template: `
    <nav class="navbar">
      <div class="navbar-brand">
        <a routerLink="/">My App</a>
      </div>
      <ul class="navbar-nav">
        <li><a routerLink="/" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">Home</a></li>
        <li><a routerLink="/about" routerLinkActive="active">About</a></li>
        <li><a routerLink="/services" routerLinkActive="active">Services</a></li>
        <li><a routerLink="/contact" routerLinkActive="active">Contact</a></li>
      </ul>
    </nav>
  `,
  styles: [`
    .navbar {
      display: flex;
      justify-content: space-between;
      align-items: center;
      background: #2c3e50;
      padding: 1rem 2rem;
      color: white;
    }
    .navbar-brand a {
      font-size: 1.5rem;
      font-weight: bold;
      color: white;
      text-decoration: none;
    }
    .navbar-nav {
      display: flex;
      list-style: none;
      margin: 0;
      padding: 0;
      gap: 2rem;
    }
    .navbar-nav a {
      color: white;
      text-decoration: none;
      padding: 0.5rem 1rem;
      border-radius: 4px;
    }
    .navbar-nav a:hover {
      background: #34495e;
    }
    .navbar-nav a.active {
      background: #3498db;
    }
  `]
})
export class NavbarComponent {}

The routerLink directive handles navigation. The routerLinkActive directive adds the active class to the current route. The routerLinkActiveOptions ensures the home link is only active on exact match. The flexbox layout keeps items aligned properly.

Adding Responsive Mobile Menu

Implement a hamburger menu for mobile devices.

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

@Component({
  selector: 'app-navbar',
  standalone: true,
  imports: [CommonModule, RouterModule],
  template: `
    <nav class="navbar">
      <div class="navbar-brand">
        <a routerLink="/">My App</a>
      </div>
      <button class="navbar-toggler" (click)="toggleMenu()">
      </button>
      <ul class="navbar-nav" [class.show]="isMenuOpen">
        <li><a routerLink="/" (click)="closeMenu()">Home</a></li>
        <li><a routerLink="/about" (click)="closeMenu()">About</a></li>
        <li><a routerLink="/services" (click)="closeMenu()">Services</a></li>
        <li><a routerLink="/contact" (click)="closeMenu()">Contact</a></li>
      </ul>
    </nav>
  `,
  styles: [`
    .navbar {
      display: flex;
      justify-content: space-between;
      align-items: center;
      background: #2c3e50;
      padding: 1rem 2rem;
      color: white;
      position: relative;
    }
    .navbar-toggler {
      display: none;
      background: none;
      border: none;
      color: white;
      font-size: 1.5rem;
      cursor: pointer;
    }
    .navbar-nav {
      display: flex;
      list-style: none;
      margin: 0;
      padding: 0;
      gap: 2rem;
    }
    @media (max-width: 768px) {
      .navbar-toggler {
        display: block;
      }
      .navbar-nav {
        display: none;
        position: absolute;
        top: 100%;
        left: 0;
        right: 0;
        background: #2c3e50;
        flex-direction: column;
        padding: 1rem;
        gap: 0;
      }
      .navbar-nav.show {
        display: flex;
      }
      .navbar-nav li {
        width: 100%;
      }
      .navbar-nav a {
        display: block;
        padding: 1rem;
      }
    }
  `]
})
export class NavbarComponent {
  isMenuOpen = false

  toggleMenu() {
    this.isMenuOpen = !this.isMenuOpen
  }

  closeMenu() {
    this.isMenuOpen = false
  }
}

The hamburger button appears on mobile devices. The isMenuOpen state controls menu visibility. The closeMenu() method hides the menu after navigation. The media query transforms the horizontal menu into a vertical dropdown on small screens.

Adding Dropdown Menus

Create dropdown submenus for nested navigation.

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

interface NavItem {
  label: string
  route?: string
  children?: NavItem[]
}

@Component({
  selector: 'app-navbar-dropdown',
  standalone: true,
  imports: [CommonModule, RouterModule],
  template: `
    <nav class="navbar">
      <div class="navbar-brand">
        <a routerLink="/">My App</a>
      </div>
      <ul class="navbar-nav">
        <li *ngFor="let item of navItems">
          <a *ngIf="!item.children" [routerLink]="item.route" routerLinkActive="active">
            {{ item.label }}
          </a>
          <div *ngIf="item.children" class="dropdown">
            <button class="dropdown-toggle">{{ item.label }}</button>
            <ul class="dropdown-menu">
              <li *ngFor="let child of item.children">
                <a [routerLink]="child.route">{{ child.label }}</a>
              </li>
            </ul>
          </div>
        </li>
      </ul>
    </nav>
  `,
  styles: [`
    .dropdown {
      position: relative;
    }
    .dropdown-toggle {
      background: none;
      border: none;
      color: white;
      cursor: pointer;
      padding: 0.5rem 1rem;
    }
    .dropdown-menu {
      display: none;
      position: absolute;
      top: 100%;
      left: 0;
      background: #34495e;
      list-style: none;
      padding: 0;
      margin: 0;
      min-width: 200px;
    }
    .dropdown:hover .dropdown-menu {
      display: block;
    }
    .dropdown-menu a {
      display: block;
      padding: 0.75rem 1rem;
      color: white;
      text-decoration: none;
    }
    .dropdown-menu a:hover {
      background: #2c3e50;
    }
  `]
})
export class NavbarDropdownComponent {
  navItems: NavItem[] = [
    { label: 'Home', route: '/' },
    {
      label: 'Products',
      children: [
        { label: 'All Products', route: '/products' },
        { label: 'Categories', route: '/products/categories' },
        { label: 'New Arrivals', route: '/products/new' }
      ]
    },
    { label: 'About', route: '/about' },
    { label: 'Contact', route: '/contact' }
  ]
}

The navItems array defines the navigation structure with optional children. Items with children render as dropdowns. The CSS :hover selector shows the dropdown menu. This provides organized navigation for complex site structures.

Adding Search Bar to Navbar

Integrate a search input in the navigation.

import { Component } from '@angular/core'
import { CommonModule } from '@angular/common'
import { RouterModule, Router } from '@angular/router'
import { FormsModule } from '@angular/forms'

@Component({
  selector: 'app-navbar-search',
  standalone: true,
  imports: [CommonModule, RouterModule, FormsModule],
  template: `
    <nav class="navbar">
      <div class="navbar-brand">
        <a routerLink="/">My App</a>
      </div>
      <ul class="navbar-nav">
        <li><a routerLink="/">Home</a></li>
        <li><a routerLink="/about">About</a></li>
      </ul>
      <form class="search-form" (submit)="handleSearch($event)">
        <input
          type="text"
          [(ngModel)]="searchQuery"
          name="search"
          placeholder="Search..."
          class="search-input"
        />
        <button type="submit" class="search-button">Search</button>
      </form>
    </nav>
  `,
  styles: [`
    .navbar {
      display: flex;
      justify-content: space-between;
      align-items: center;
      background: #2c3e50;
      padding: 1rem 2rem;
    }
    .search-form {
      display: flex;
      gap: 0.5rem;
    }
    .search-input {
      padding: 0.5rem;
      border: none;
      border-radius: 4px;
    }
    .search-button {
      padding: 0.5rem 1rem;
      background: #3498db;
      color: white;
      border: none;
      border-radius: 4px;
      cursor: pointer;
    }
  `]
})
export class NavbarSearchComponent {
  searchQuery = ''

  constructor(private router: Router) {}

  handleSearch(event: Event) {
    event.preventDefault()
    if (this.searchQuery.trim()) {
      this.router.navigate(['/search'], { queryParams: { q: this.searchQuery } })
      this.searchQuery = ''
    }
  }
}

The search form uses [(ngModel)] for two-way binding. The handleSearch method navigates to the search results page with the query as a parameter. The form prevents default submission. This provides inline search functionality without leaving the page.

Adding User Profile Menu

Create an authenticated user dropdown with profile options.

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

@Component({
  selector: 'app-navbar-profile',
  standalone: true,
  imports: [CommonModule, RouterModule],
  template: `
    <nav class="navbar">
      <div class="navbar-brand">
        <a routerLink="/">My App</a>
      </div>
      <ul class="navbar-nav">
        <li><a routerLink="/">Home</a></li>
        <li><a routerLink="/about">About</a></li>
      </ul>
      <div class="user-menu">
        <button class="user-button" (click)="toggleUserMenu()">
          <img [src]="userAvatar" alt="User" class="avatar" />
          {{ userName }}
        </button>
        <ul class="user-dropdown" *ngIf="isUserMenuOpen">
          <li><a routerLink="/profile">Profile</a></li>
          <li><a routerLink="/settings">Settings</a></li>
          <li><hr /></li>
          <li><a (click)="logout()">Logout</a></li>
        </ul>
      </div>
    </nav>
  `,
  styles: [`
    .user-menu {
      position: relative;
    }
    .user-button {
      display: flex;
      align-items: center;
      gap: 0.5rem;
      background: none;
      border: none;
      color: white;
      cursor: pointer;
    }
    .avatar {
      width: 32px;
      height: 32px;
      border-radius: 50%;
    }
    .user-dropdown {
      position: absolute;
      top: 100%;
      right: 0;
      background: white;
      border: 1px solid #ddd;
      border-radius: 4px;
      list-style: none;
      padding: 0.5rem 0;
      margin: 0.5rem 0 0;
      min-width: 150px;
      box-shadow: 0 2px 8px rgba(0,0,0,0.15);
    }
    .user-dropdown a {
      display: block;
      padding: 0.5rem 1rem;
      color: #333;
      text-decoration: none;
      cursor: pointer;
    }
    .user-dropdown a:hover {
      background: #f5f5f5;
    }
    .user-dropdown hr {
      margin: 0.5rem 0;
      border: none;
      border-top: 1px solid #ddd;
    }
  `]
})
export class NavbarProfileComponent {
  userName = 'John Doe'
  userAvatar = 'https://via.placeholder.com/32'
  isUserMenuOpen = false

  toggleUserMenu() {
    this.isUserMenuOpen = !this.isUserMenuOpen
  }

  logout() {
    console.log('Logging out...')
    this.isUserMenuOpen = false
  }
}

The user button displays the avatar and name. The isUserMenuOpen controls dropdown visibility. The dropdown includes profile links and logout action. This provides quick access to user-specific features.

Best Practice Note

This is the same navbar architecture we use in CoreUI Angular templates for consistent navigation across applications. For production apps, add keyboard navigation support (Tab, Enter, Escape) for accessibility. Implement click-outside detection to close dropdowns and mobile menus. Consider adding scroll behavior that hides or shrinks the navbar on scroll down. For multi-level navigation, use CoreUI’s CNavbar component which provides a fully accessible, feature-rich navigation bar with responsive behavior, dropdowns, and mobile menu handling out of the box. The CoreUI navbar handles complex layouts, branding, search integration, and user menus professionally.


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.

Answers by CoreUI Core Team