A common user experience utilizes breadcrumbs for user navigation.  Typically these links mimic a sitemap.xml file that search engines will crawl and index the URLs provided.  Or a session based store could push and pop crumbs on a stack for display.

In Angular, the router configures navigable components and modules.  The modules can be lazy-loaded, so routes may not necessarily be known ahead of time.  This becomes more evident as large teams delineate ownership and start following a microservice pattern for front end development, using microfrontends.

In this tutorial, I'll explain and provide you the code and resources to use building your own breadcrumb.

@ngserveio/navigation
Find more at libraries and examples at [NgServe.io](https://ngserve.io).

Goals

1. Define the Breadcrumb Model

2.  Configure Route Data

3. Create a Breadcrumb Factory Service

4. The Router and Breadcrumb Service

5. Breadcrumb Component Responsibility

1. Define the Breadcrumb Model

The breadcrumb text displayed could be static or dynamic.  Static names could include Home, Cart, About Us.  The dynamic crumb names could change based on any number of factors.  Examples of that would include, a product name, blog name, or even displaying the count of cart items.  Its the dynamic crumb names that pose some challenges.  In order to respond to changing values of dynamic routes, the label property implements an Observable<string>.  The icon property supports displaying an image or material font icon also in the form of an Observable<string>.  path defines the url to navigate.

Each breadcrumb could have a different implementation in display of  breadcrumb label.  The route parameters, state of the application (items in the cart), or a static value such as Home could display as one of the crumbs.  In order to determine how to display these crumbs, a service definition in IBreadCrumbRouteConfig needs to be defined.  The providerKey will define the service that renders the label.

Free Your Developers

Nx Monorepo Starter alleviates developers from re-inventing deployments on popular Google Cloud Services, standardizes on libraries, and saves time for scaffolding projects.

View on Gumroad

2. Configure the Route Data

Each route's data configures the breadcrumb for displaying names within the trail.  Skipping the configuration will exclude the route from the crumb trail.

The consuming module configures the key / service value pairs for the factory to instantiate.

The BreadcrumbServiceFactory finds the providerKey on the route data and instantiates the appropriate breadcrumb label service.

3. Create the Breadcrumb Factory Service

The factory service chooses the service based on the key provided as configured in the IBreadcrumbRouteConfig.  This allows teams flexibility for rendering the label of the Breadcrumb.  Each service registered implements an interface IBreadcrumbLabelService.  

4. The Router and BreadcrumbService

The BreadcrumbService traverses the active route, reads the data for the IBreadcrumbConfig, and utilizes the BreadcrumbFactory to return the correct label.  The providerKey helps map location of the service responsible for creating the individual crumb.

Each one of the label services inherits from an abstract class BaseBreadcrumbService which provides the ability to create the path for the label from the current route.

5. Breadcrumb Component Responsibility

The breadcrumb allows consumers of the component to define its own crumb child components.  It injects the BreadcrumbService reading all the breadcrumb configuration on each route.  It allows the BreadcrumbFactoryService to determine which service will render the crumb.

The template provides context to the child outlet templates, supplying each crumb as a template variable into the child outlet template.  The templateRef input defines the child component template for each crumb, allowing flexibility for templating the individual crumbs.  It will be the responsibility of the consuming app to define its own breadcrumb presentation template while leaving the Breadcrumb component to supply the data.

Conclusion

A model of path, label, and icon allows developers enough information to create a specific crumb.  The label property is an Observable allowing flexibility of the breadcrumb service to provide an appropriate observable for display, e.g. number of cart items.

Each route with a crumb configures the data property on the route to define the crumb label service via a providerKey as a property on the data.crumb.  Services configured as providers with this key will be instantiated via the BreadCrumbFactory to map breadcrumb services.

Each service implements a getCrumb method which returns the breadcrumb model.

Finally, the component helps render the crumbs but leaves the consuming component to render the crumb.

Import the @ngserveio/navigation package into your project to start using the breadcrumb in your Angular Project.