Search code examples
angularbreadcrumbs

How can I create breadcrumb in Angular


I want to add breadcrumb to my page. I have many routes and none of them have children.

I tried to do it by creating a child, but there are too many redirects to common pages. For example;

Home > Library > Lessons > Lesson Name

Assigned Lessons > Lesson Name

When the route of the course names is the same, how should I child them or is there a way to do it without following the route?

I tried to do it according to the route, the result I expected was;

Home > Library > Lessons > Lesson Name Assigned Lessons > Lesson Name

But when I do it, when it comes to the lesson name, it automatically happens like this;

Home > Library > Lessons > Lesson Name


Solution

  • Here's a simple way to add breadcrumbs in Angular:

    1. Create a Breadcrumb Service:
    // breadcrumb.service.ts
    import { Injectable } from '@angular/core';
    import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
    import { filter } from 'rxjs/operators';
    
    @Injectable({
      providedIn: 'root',
    })
    export class BreadcrumbService {
      breadcrumbs: Array<{ label: string, url: string }> = [];
    
      constructor(private router: Router, private activatedRoute: ActivatedRoute) {
        this.router.events.pipe(
          filter(event => event instanceof NavigationEnd)
        ).subscribe(() => {
          this.breadcrumbs = this.createBreadcrumbs(this.activatedRoute.root);
        });
      }
    
      private createBreadcrumbs(route: ActivatedRoute, url: string = '', breadcrumbs: Array<{ label: string, url: string }> = []): Array<{ label: string, url: string }> {
        const children: ActivatedRoute[] = route.children;
    
        if (children.length === 0) {
          return breadcrumbs;
        }
    
        for (const child of children) {
          const routeURL: string = child.snapshot.url.map(segment => segment.path).join('/');
          if (routeURL !== '') {
            url += `/${routeURL}`;
          }
    
          breadcrumbs.push({ label: child.snapshot.data['breadcrumb'], url: url });
          return this.createBreadcrumbs(child, url, breadcrumbs);
        }
    
        return breadcrumbs;
      }
    }
    
    1. Set Breadcrumb Data in Your Routes:
    // app-routing.module.ts
    const routes: Routes = [
      {
        path: 'home',
        component: HomeComponent,
        data: { breadcrumb: 'Home' },
      },
      {
        path: 'library',
        component: LibraryComponent,
        data: { breadcrumb: 'Library' },
        children: [
          {
            path: 'lessons',
            component: LessonsComponent,
            data: { breadcrumb: 'Lessons' },
            children: [
              {
                path: ':lessonName',
                component: LessonDetailComponent,
                data: { breadcrumb: 'Lesson Name' },
              },
            ],
          },
          // Other library routes...
        ],
      },
      // Other routes...
    ];
    
    1. Display Breadcrumbs in Your Component:
    // breadcrumb.component.ts
    import { Component, OnInit } from '@angular/core';
    import { BreadcrumbService } from './breadcrumb.service';
    
    @Component({
      selector: 'app-breadcrumb',
      templateUrl: './breadcrumb.component.html',
      styleUrls: ['./breadcrumb.component.css'],
    })
    export class BreadcrumbComponent implements OnInit {
      breadcrumbs: Array<{ label: string, url: string }> = [];
    
      constructor(private breadcrumbService: BreadcrumbService) {}
    
      ngOnInit(): void {
        this.breadcrumbs = this.breadcrumbService.breadcrumbs;
      }
    }
    
    1. Use Breadcrumb Component in Your Layout:
    <!-- app.component.html -->
    <app-breadcrumb></app-breadcrumb>
    <router-outlet></router-outlet>
    
    1. Create Breadcrumb Template: Create a template for displaying breadcrumbs.
    <!-- breadcrumb.component.html -->
    <nav>
      <ng-container *ngFor="let breadcrumb of breadcrumbs; let last = last">
        <ng-container *ngIf="!last">
          <a [routerLink]="breadcrumb.url">{{ breadcrumb.label }}</a> &gt;
        </ng-container>
        <ng-container *ngIf="last">
          {{ breadcrumb.label }}
        </ng-container>
      </ng-container>
    </nav>