Icon library service for efficiently managing Font Awesome icon definitions, adding individual icons or complete icon packs, and retrieving icons by prefix and name. The library system enables tree-shaking and optimal bundle sizes.
Injectable service for managing icon definitions throughout the application.
@Injectable({ providedIn: 'root' })
class FaIconLibrary implements FaIconLibraryInterface {
/** Add individual icon definitions to the library */
addIcons(...icons: IconDefinition[]): void;
/** Add complete icon packs to the library */
addIconPacks(...packs: IconPack[]): void;
/** Retrieve an icon definition by prefix and name */
getIconDefinition(prefix: IconPrefix, name: IconName): IconDefinition | null;
}
interface FaIconLibraryInterface {
addIcons(...icons: IconDefinition[]): void;
addIconPacks(...packs: IconPack[]): void;
getIconDefinition(prefix: IconPrefix, name: IconName): IconDefinition | null;
}Tree-shakable approach for adding only needed icons to reduce bundle size.
import { Component } from '@angular/core';
import { FaIconLibrary } from '@fortawesome/angular-fontawesome';
import {
faCoffee,
faHome,
faUser,
faSpinner
} from '@fortawesome/free-solid-svg-icons';
import { faHeart } from '@fortawesome/free-regular-svg-icons';
import { faGithub } from '@fortawesome/free-brands-svg-icons';
@Component({
selector: 'app-root',
template: `
<fa-icon icon="coffee"></fa-icon>
<fa-icon [icon]="['far', 'heart']"></fa-icon>
<fa-icon [icon]="['fab', 'github']"></fa-icon>
`
})
export class AppComponent {
constructor(library: FaIconLibrary) {
// Add individual icons (recommended for tree-shaking)
library.addIcons(
faCoffee,
faHome,
faUser,
faSpinner,
faHeart,
faGithub
);
}
}Convenient approach for adding complete icon sets, though less optimal for bundle size.
import { Component } from '@angular/core';
import { FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { fas } from '@fortawesome/free-solid-svg-icons';
import { far } from '@fortawesome/free-regular-svg-icons';
import { fab } from '@fortawesome/free-brands-svg-icons';
@Component({
selector: 'app-root',
template: `
<!-- All solid icons available -->
<fa-icon icon="coffee"></fa-icon>
<fa-icon icon="home"></fa-icon>
<fa-icon icon="star"></fa-icon>
<!-- All regular icons available -->
<fa-icon [icon]="['far', 'heart']"></fa-icon>
<fa-icon [icon]="['far', 'star']"></fa-icon>
<!-- All brand icons available -->
<fa-icon [icon]="['fab', 'github']"></fa-icon>
<fa-icon [icon]="['fab', 'twitter']"></fa-icon>
`
})
export class AppComponent {
constructor(library: FaIconLibrary) {
// Add entire icon packs (increases bundle size)
library.addIconPacks(fas, far, fab);
}
}Recommended pattern for organizing icon imports at the module level.
import { NgModule } from '@angular/core';
import { FontAwesomeModule, FaIconLibrary } from '@fortawesome/angular-fontawesome';
import {
faCoffee,
faHome,
faUser,
faCog,
faSpinner,
faCheck,
faTimes
} from '@fortawesome/free-solid-svg-icons';
@NgModule({
imports: [FontAwesomeModule],
exports: [FontAwesomeModule]
})
export class IconsModule {
constructor(library: FaIconLibrary) {
// Add icons used throughout the application
library.addIcons(
faCoffee,
faHome,
faUser,
faCog,
faSpinner,
faCheck,
faTimes
);
}
}
// Use in app module
@NgModule({
imports: [IconsModule],
// ...
})
export class AppModule {}Dynamic icon loading for specific features or routes.
import { Component, OnInit } from '@angular/core';
import { FaIconLibrary } from '@fortawesome/angular-fontawesome';
@Component({
selector: 'app-chart-component',
template: `
<fa-icon icon="chart-bar" *ngIf="chartsLoaded"></fa-icon>
<fa-icon icon="chart-pie" *ngIf="chartsLoaded"></fa-icon>
<fa-icon icon="spinner" animation="spin" *ngIf="!chartsLoaded"></fa-icon>
`
})
export class ChartComponent implements OnInit {
chartsLoaded = false;
constructor(private library: FaIconLibrary) {}
async ngOnInit() {
// Lazy load chart icons when component initializes
const chartIcons = await import('@fortawesome/free-solid-svg-icons').then(
icons => [icons.faChartBar, icons.faChartPie, icons.faChartLine]
);
this.library.addIcons(...chartIcons);
this.chartsLoaded = true;
}
}Checking icon availability and handling missing icons.
class IconValidationService {
constructor(private library: FaIconLibrary) {}
/** Check if an icon exists in the library */
hasIcon(prefix: IconPrefix, name: IconName): boolean {
return this.library.getIconDefinition(prefix, name) !== null;
}
/** Get icon or return fallback */
getIconSafe(prefix: IconPrefix, name: IconName, fallback?: IconDefinition): IconDefinition | null {
const icon = this.library.getIconDefinition(prefix, name);
return icon || fallback || null;
}
/** Validate required icons are loaded */
validateRequiredIcons(requiredIcons: Array<[IconPrefix, IconName]>): string[] {
const missing = requiredIcons.filter(([prefix, name]) =>
!this.hasIcon(prefix, name)
);
return missing.map(([prefix, name]) => `${prefix}:${name}`);
}
}Usage Example:
@Component({
selector: 'app-validated-icons',
template: `
<fa-icon [icon]="['fas', 'coffee']" *ngIf="hasIcon('fas', 'coffee')"></fa-icon>
<span *ngIf="!hasIcon('fas', 'coffee')" class="missing-icon">
☕ (Icon not loaded)
</span>
`
})
export class ValidatedIconsComponent {
constructor(
private library: FaIconLibrary,
private iconValidator: IconValidationService
) {}
hasIcon(prefix: IconPrefix, name: IconName): boolean {
return this.iconValidator.hasIcon(prefix, name);
}
ngOnInit() {
const required = [
['fas', 'coffee'] as [IconPrefix, IconName],
['fas', 'home'] as [IconPrefix, IconName]
];
const missing = this.iconValidator.validateRequiredIcons(required);
if (missing.length > 0) {
console.warn('Missing required icons:', missing);
}
}
}Creating custom aliases for commonly used icons.
import { FaIconLibrary } from '@fortawesome/angular-fontawesome';
import { faCoffee, faHome, faUser } from '@fortawesome/free-solid-svg-icons';
@Injectable()
export class CustomIconService {
private iconAliases = new Map<string, IconDefinition>();
constructor(private library: FaIconLibrary) {
this.setupAliases();
}
private setupAliases(): void {
// Create custom aliases
this.iconAliases.set('drink', faCoffee);
this.iconAliases.set('house', faHome);
this.iconAliases.set('person', faUser);
// Add to library with original names
this.library.addIcons(faCoffee, faHome, faUser);
}
getIconByAlias(alias: string): IconDefinition | null {
return this.iconAliases.get(alias) || null;
}
getAllAliases(): string[] {
return Array.from(this.iconAliases.keys());
}
}Managing Font Awesome Pro icons with proper licensing.
import { FaIconLibrary } from '@fortawesome/angular-fontawesome';
// Pro imports (requires valid license)
import {
faHome as fasHome,
faCoffee as fasCoffee
} from '@fortawesome/pro-solid-svg-icons';
import {
faHome as farHome,
faCoffee as farCoffee
} from '@fortawesome/pro-regular-svg-icons';
import {
faHome as falHome,
faCoffee as falCoffee
} from '@fortawesome/pro-light-svg-icons';
import {
faHome as fatHome,
faCoffee as fatCoffee
} from '@fortawesome/pro-thin-svg-icons';
import { fad } from '@fortawesome/pro-duotone-svg-icons';
@Component({
selector: 'app-pro-icons',
template: `
<!-- Multiple weights of same icon -->
<fa-icon [icon]="['fas', 'home']"></fa-icon> <!-- Solid -->
<fa-icon [icon]="['far', 'home']"></fa-icon> <!-- Regular -->
<fa-icon [icon]="['fal', 'home']"></fa-icon> <!-- Light -->
<fa-icon [icon]="['fat', 'home']"></fa-icon> <!-- Thin -->
<!-- Duotone icons -->
<fa-duotone-icon [icon]="['fad', 'coffee']"></fa-duotone-icon>
`
})
export class ProIconsComponent {
constructor(library: FaIconLibrary) {
// Add pro icons with different weights
library.addIcons(
fasHome, farHome, falHome, fatHome,
fasCoffee, farCoffee, falCoffee, fatCoffee
);
// Add duotone pack
library.addIconPacks(fad);
}
}Best practices for optimal library performance.
// Performance tips:
// 1. Use addIcons() for tree-shaking instead of addIconPacks()
// 2. Load icons in app initialization, not in components
// 3. Use icon validation to catch missing icons early
// 4. Consider lazy loading for large icon sets
// 5. Group related icons in feature modulesOptimized Setup:
// icons.service.ts - Centralized icon management
@Injectable({ providedIn: 'root' })
export class IconsService {
private coreIcons = [
faCoffee, faHome, faUser, faCog, faSpinner, faCheck, faTimes
];
private chartIcons = [
faChartBar, faChartPie, faChartLine
];
constructor(private library: FaIconLibrary) {
this.loadCoreIcons();
}
loadCoreIcons(): void {
this.library.addIcons(...this.coreIcons);
}
async loadChartIcons(): Promise<void> {
this.library.addIcons(...this.chartIcons);
}
getLoadedIconsCount(): number {
// Get count of loaded icons (implementation depends on library internals)
return Object.keys((this.library as any).definitions).length;
}
}Troubleshooting common icon library issues.
@Injectable()
export class IconDebugService {
constructor(private library: FaIconLibrary) {}
debugIconLibrary(): void {
console.group('FontAwesome Library Debug');
// Check library state
const definitions = (this.library as any).definitions;
console.log('Loaded prefixes:', Object.keys(definitions));
Object.entries(definitions).forEach(([prefix, icons]) => {
console.log(`${prefix}:`, Object.keys(icons as object).length, 'icons');
});
console.groupEnd();
}
findIcon(query: string): void {
const definitions = (this.library as any).definitions;
const results: string[] = [];
Object.entries(definitions).forEach(([prefix, icons]) => {
Object.keys(icons as object).forEach(iconName => {
if (iconName.includes(query)) {
results.push(`${prefix}:${iconName}`);
}
});
});
console.log(`Icons matching "${query}":`, results);
}
}
// Usage in development
if (!environment.production) {
injector.get(IconDebugService).debugIconLibrary();
}