A flexible and reusable breadcrumb component for Angular applications that automatically generates breadcrumbs based on your routing configuration.
npm install ng-hub-ui-breadcrumbs
- Automatic breadcrumb generation from route configuration
- Customizable through CSS variables
- RTL support
- Templating support for custom breadcrumb items
- Bootstrap-compatible styling
You can use this component in two ways:
Import the required artifacts in your component:
import { HubBreadcrumbComponent } from 'ng-hub-ui-breadcrumbs';
import { HubBreadcrumbItemDirective } from 'ng-hub-ui-breadcrumbs';
@Component({
// ...
imports: [HubBreadcrumbComponent, HubBreadcrumbItemDirective]
})
If you prefer using NgModules, import the HubBreadcrumbModule:
import { HubBreadcrumbModule } from 'ng-hub-ui-breadcrumbs';
@NgModule({
imports: [HubBreadcrumbModule]
})
export class AppModule { }
Configure your routes with breadcrumb data:
// app-routing.module.ts
const routes: Routes = [
{
path: '',
data: { breadcrumb: 'Home' }
},
{
path: 'products',
data: { breadcrumb: 'Products' },
children: [
{
path: ':id',
resolve: {
resolvedData: ProductResolver
},
data: {
breadcrumb: '{name}' // Will use the product name from resolver
}
}
]
}
];
Add the component to your template:
<hub-breadcrumbs></hub-breadcrumbs>
You can also use functions to generate dynamic labels:
const routes: Routes = [
{
path: 'products',
resolve: { info: infoResolver },
data: { breadcrumb: (data: any) => `${data.info.title}` },
}
];
The breadcrumb component automatically:
- Listens to route changes
- Extracts breadcrumb data from route configuration
- Builds the breadcrumb path
- Handles template customization
- Supports RTL languages
For lazy-loaded modules, configure the parent route with breadcrumb data:
// app-routing.module.ts
const routes: Routes = [
{
path: 'admin',
data: { breadcrumb: 'Administration' },
loadChildren: () => import('./admin/admin.module').then(m => m.AdminModule)
}
];
// admin-routing.module.ts
const adminRoutes: Routes = [
{
path: 'users',
data: { breadcrumb: 'Users' }
}
];
This will generate breadcrumbs like: Home > Administration > Users
You can customize how each breadcrumb item is rendered using a template.
<hub-breadcrumbs>
<ng-template hubBreadcrumbItem let-item let-isLast="isLast">
@if (!isLast) {
<a [routerLink]="item.url" class="hub-breadcrumb__link">
{{ item.label }}
</a>
} @else {
<span class="hub-breadcrumb__text">{{ item.label }}</span>
}
</ng-template>
</hub-breadcrumbs>
The template context provides these properties:
interface BreadcrumbTemplateContext {
$implicit: BreadcrumbItem; // The current breadcrumb item
isLast: boolean; // Whether this is the last item
}
interface BreadcrumbItem {
label: string; // The text to display
url: string; // The route URL
data: any; // Additional data from route configuration
}
With icons:
<hub-breadcrumbs>
<ng-template hubBreadcrumbItem let-item let-isLast="isLast">
@if (!isLast) {
<a [routerLink]="item.url" class="hub-breadcrumb__link">
<i [class]="item.data?.icon"></i>
{{ item.label }}
</a>
} @else {
<span class="hub-breadcrumb__text">
<i [class]="item.data?.icon"></i>
{{ item.label }}
</span>
}
</ng-template>
</hub-breadcrumbs>
Route configuration for icons:
const routes: Routes = [
{
path: 'products',
data: {
breadcrumb: 'Products',
icon: 'fa fa-box' // Will be available in template
}
}
];
With custom separators:
<hub-breadcrumbs>
<ng-template hubBreadcrumbItem let-item let-isLast="isLast">
@if (!isLast) {
<a [routerLink]="item.url" class="hub-breadcrumb__link">
{{ item.label }}
</a>
<span class="hub-breadcrumb__separator">→</span>
} @else {
<span class="hub-breadcrumb__text">{{ item.label }}</span>
}
</ng-template>
</hub-breadcrumbs>
Note: When using a custom template, you're responsible for:
- Handling the navigation with
routerLink
- Managing active/inactive states
- Applying appropriate styles
- Handling RTL if needed
The breadcrumb component uses CSS variables for styling, making it highly customizable. It's designed to work with or without Bootstrap.
These SCSS variables set the default values:
$border-radius-pill: 50rem !default;
$secondary-color: black !default;
$breadcrumb-font-size: null !default;
$breadcrumb-padding-y: 0.25rem !default;
$breadcrumb-padding-x: 1rem !default;
$breadcrumb-item-padding-x: 0.5rem !default;
$breadcrumb-margin-bottom: 0 !default;
$breadcrumb-bg: white !default;
$breadcrumb-divider-color: $secondary-color !default;
$breadcrumb-active-color: $secondary-color !default;
$breadcrumb-divider: quote('>') !default;
$breadcrumb-divider-flipped: $breadcrumb-divider !default;
$breadcrumb-border-radius: $border-radius-pill !default;
These variables are exposed for runtime customization:
.hub-breadcrumb__list {
--hub-breadcrumb-padding-x: 1rem;
--hub-breadcrumb-padding-y: 0.25rem;
--hub-breadcrumb-margin-bottom: 0;
--hub-breadcrumb-bg: white;
--hub-breadcrumb-border-radius: 50rem;
--hub-breadcrumb-divider-color: black;
--hub-breadcrumb-item-padding-x: 0.5rem;
--hub-breadcrumb-item-active-color: black;
}
- Override SCSS variables (compile-time):
// your-styles.scss
$breadcrumb-bg: #f8f9fa;
$breadcrumb-divider: quote('→');
$breadcrumb-active-color: #6c757d;
- Override CSS variables (runtime):
.hub-breadcrumb__list {
--hub-breadcrumb-bg: #f8f9fa;
--hub-breadcrumb-divider-color: #6c757d;
}
- Override classes directly:
.hub-breadcrumb__item {
&--active {
font-weight: bold;
}
}
The component automatically handles RTL languages by flipping the divider. You can customize the flipped divider using:
$breadcrumb-divider-flipped: quote('<');
The component uses BEM methodology:
-
.hub-breadcrumb
- Block (host component) -
.hub-breadcrumb__list
- Element (container) -
.hub-breadcrumb__item
- Element (each breadcrumb) -
.hub-breadcrumb__item--active
- Modifier (active state)
While the component works independently, it's designed to be compatible with Bootstrap's breadcrumb styles. If you're using Bootstrap, the styles will automatically align with your Bootstrap theme.
You can customize the breadcrumb directly in your template using inline styles:
<hub-breadcrumbs style="
--hub-breadcrumb-divider: '🐸';
--hub-breadcrumb-bg: #e9ecef;
--hub-breadcrumb-item-active-color: #0d6efd;
"></hub-breadcrumbs>
Common use cases:
- Custom divider:
<hub-breadcrumbs style="--hub-breadcrumb-divider: '→'"></hub-breadcrumbs>
<hub-breadcrumbs style="--hub-breadcrumb-divider: '>'"></hub-breadcrumbs>
<hub-breadcrumbs style="--hub-breadcrumb-divider: '/'"></hub-breadcrumbs>
<hub-breadcrumbs style="--hub-breadcrumb-divider: '🐸'"></hub-breadcrumbs>
- Custom colors:
<hub-breadcrumbs style="
--hub-breadcrumb-bg: transparent;
--hub-breadcrumb-divider-color: #6c757d;
--hub-breadcrumb-item-active-color: #0d6efd;
"></hub-breadcrumbs>
- Custom spacing:
<hub-breadcrumbs style="
--hub-breadcrumb-padding-x: 0;
--hub-breadcrumb-padding-y: 0;
--hub-breadcrumb-item-padding-x: 1rem;
"></hub-breadcrumbs>
Note: When using emojis or special characters as dividers, make sure to wrap them in quotes.
@Component({
selector: 'hub-breadcrumb',
standalone: true
})
A standalone component that automatically generates breadcrumbs from route configuration.
@Directive({
selector: '[hubBreadcrumbItem]',
standalone: true
})
Template directive for customizing breadcrumb item rendering.
interface BreadcrumbItem {
label: string; // Display text
url: string; // Navigation URL
data: any; // Additional data from route configuration
}
interface BreadcrumbTemplateContext {
$implicit: BreadcrumbItem; // Current breadcrumb item
isLast: boolean; // Whether this is the last item
}
The component reads breadcrumb configuration from route data:
interface BreadcrumbRouteData {
breadcrumb: string | ((data: any) => string); // Static text or function
icon?: string; // Optional icon class
[key: string]: any; // Additional custom data
}
Property | Description | Default |
---|---|---|
--hub-breadcrumb-padding-x |
Horizontal padding | 1rem |
--hub-breadcrumb-padding-y |
Vertical padding | 0.25rem |
--hub-breadcrumb-margin-bottom |
Bottom margin | 0 |
--hub-breadcrumb-bg |
Background color | white |
--hub-breadcrumb-border-radius |
Border radius | 50rem |
--hub-breadcrumb-divider-color |
Divider color | black |
--hub-breadcrumb-item-padding-x |
Item spacing | 0.5rem |
--hub-breadcrumb-item-active-color |
Active item color | black |
Variable | Description | Default |
---|---|---|
$breadcrumb-padding-y |
Vertical padding | 0.25rem |
$breadcrumb-padding-x |
Horizontal padding | 1rem |
$breadcrumb-margin-bottom |
Bottom margin | 0 |
$breadcrumb-bg |
Background color | white |
$breadcrumb-divider |
Divider character | '>' |
$breadcrumb-divider-flipped |
RTL divider character | Same as $breadcrumb-divider
|
$breadcrumb-border-radius |
Border radius | 50rem |
$breadcrumb-active-color |
Active item color | black |
We appreciate your interest in contributing to Hub Breadcrumb! Here's how you can help:
- Clone the repository
git clone https://github.com/carlos-morcillo/ng-hub-ui-breadcrumbs.git
cd ng-hub-ui-breadcrumbs
- Install dependencies
npm install
- Start the development server
npm start
Run the test suite:
# Unit tests
npm run test
# E2E tests
npm run e2e
# Test coverage
npm run test:coverage
ng-hub-ui-breadcrumbs/
├── src/
│ ├── lib/
│ │ ├── components/
│ │ │ ├── hub-breadcrumb.component.ts
│ │ │ ├── hub-breadcrumb.component.spec.ts
│ │ │ └── hub-breadcrumb.component.scss
│ │ ├── directives/
│ │ │ └── hub-breadcrumb-item.directive.ts
│ │ ├── services/
│ │ │ └── hub-breadcrumb.service.ts
│ │ └── interfaces/
│ │ └── breadcrumb-item.ts
│ └── public-api.ts
├── README.md
└── package.json
We follow Conventional Commits:
-
feat:
New features -
fix:
Bug fixes -
docs:
Documentation changes -
style:
Code style changes (formatting, etc) -
refactor:
Code refactors -
test:
Adding or updating tests -
chore:
Maintenance tasks
Example:
git commit -m "feat: add custom divider support"
- Fork the repository
- Create a new branch:
git checkout -b feat/my-new-feature
- Make your changes
- Add tests for any new functionality
- Update documentation if needed
- Submit a Pull Request
- Write unit tests for new features
- Follow Angular style guide
- Update documentation for API changes
- Maintain backward compatibility
- Add comments for complex logic
Before creating an issue, please:
- Check existing issues
- Use the issue template
- Include reproduction steps
- Specify your environment
We follow the Angular Style Guide:
- Use TypeScript
- Follow BEM for CSS
- Maintain consistent naming
- Add JSDoc comments
If you find this project helpful and would like to support its development, you can buy me a coffee:
Your support is greatly appreciated and helps maintain and improve this project!
This project is licensed under the MIT License - see the LICENSE file for details.
Made with ❤️ by [Carlos Morcillo Fernández]