Intro Every Front-End application includes a lot of media content. Today, I would like to talk about a small part of media content management - how to deal with icons in your application. Why should you use SVG in your application? Well, there are some advantages in comparison with raster one: SVG SVG icons can shrink and grow at any size you want without quality loss; Scalability: Customization. You can colorize your icons by simply adding a property and voilà - you have it; color CSS Usually, SVG icons are very tiny, and this fact positively impacts the vital performance metrics; Size: Since SVG is XML-based, you can put their description or title for elements inside, which enhances the experience for people with disabilities and makes your application more friendly for search engines. Accessibility: Problem statement Let's look into the ways of using SVG icons in an application. Generally, we can handle it in different ways: Use CSS property. One of the easiest ways to use any type of content in an application; background Create a script that will collect all of your icons and put them into an index.html file. Then, create a component that uses icons via tag and attribute like this: use href <svg> <use [attr.xlink:href]="'#app-icon-' + iconName" /> </svg> This approach isn't obvious and can lead to performance issues since you can add some icons with large sizes, and they will be included (even if they aren't used) in your after an application build. This approach has been used for a long time in my current project. It became an issue when we added some icons with a size of about 350 KB, and it increased our index.html by more than three times (from 130KB to 430KB) index.html Create a component that will load an icon from the icons folder when you need it by passing only an icon name. This solution will be described below in detail Solution There is a code of a shared component: import { HttpClient } from '@angular/common/http'; import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnInit } from '@angular/core'; import { DomSanitizer, SafeHtml } from '@angular/platform-browser'; import { map, shareReplay } from 'rxjs/operators'; import { SvgIconService } from './svg-icon.service'; @Component({ changeDetection: ChangeDetectionStrategy.OnPush, selector: 'app-svg-icon', styleUrls: ['./svg-icon.component.less'], // *1 template: ` <div [innerHTML]="sanitizedSvgContent"></div>`, }) export class SvgIconComponent implements OnInit { @Input() public iconName!: string; public sanitizedSvgContent: SafeHtml; constructor( private cdr: ChangeDetectorRef, private sanitizer: DomSanitizer, private http: HttpClient, private svgIconService: SvgIconService, ) {} // *2 public ngOnInit(): void { this.loadSvg(); } // *3 private loadSvg(): void { // Exit from the method in case of icon absence if (!this.iconName) return; // Construct your path to an icon const svgPath = `/icons/svg/${this.iconName}.svg`; // Check if the icon is already cached if (!this.svgIconService.svgIconMap.has(svgPath)) { // *4 const svg$ = this.http.get(svgPath, { responseType: 'text' }).pipe( map((svg) => this.sanitizer.bypassSecurityTrustHtml(svg)), shareReplay(1), ); // Cache the result: iconName as a key and Observable as a value this.svgIconService.svgIconMap.set(svgPath, svg$); } // Get an Observable with sanitized SVG from the Map const cachedSvg$ = this.svgIconService.svgIconMap.get(svgPath); // Subscribe to the Observable to get the content cachedSvg$.subscribe( (svg) => { // Set it to the property this.sanitizedSvgContent = svg; // Trigger the 'detectChanges' method for UI updating this.cdr.detectChanges(); }, // Simple error handling in case of any issue related to icon loading (error) => console.error(`Error loading SVG`, error), ); } } Some important comments for this code snippet: For the template, we use just element with the property, which allows us to insert any HTML as a string. In this place, we insert our SVG icons; div innerHTML In the method we invoke the method, which handles the whole logic of getting a particular icon; ngOnInit loadSvg We must use caching to store already loaded icons. It will prevent unnecessary repeating loading (you can notice it when you use this component for repeated content generation - dashboard rows, tiles, list options, etc.). For this, we use a separate service with only one field - which is ; SvgIconService svgIconMap Map @Injectable({ providedIn: 'root', }) export class SvgIconService { public svgIconMap: Map<string, Observable<SafeHtml>> = new Map<string, Observable<SafeHtml>>(); } We use for loading an icon by path. For operators, we use function, which returns sanitized content (we simply skip checking this content since we trust the source. If you load icons from sources that you do not trust 100% - it's better to use the function), and to ensure that the HTTP request is made only once, and future subscribers to this will immediately retrieve an icon. HttpClient map sanitize shareReplay Observable Let's see the styles for this component: :host { display: inline-block; height: 18px; width: 18px; color: inherit; } div { &::ng-deep svg { display: block; height: 100%; width: 100%; color: inherit; fill: currentColor; } } We set the and the to a element for the easiest way of size overriding - you can set any size you want outside by simply adding the and properties; width height host width height For the SVG element, we set and for the same purpose - to get an opportunity for style override outside the component. Adding the , , and properties ensures that the icon will take all available space. color fill display height width With this solution, the has been reduced from 430KB to 6KB, which index.html improved Page Load Time for 100-150ms in average. Before using this component make sure that your icons are in the folder. You can make it by adding them to the property of the . dist assets angular.json Usage example Just add the new component by selector and pass an icon name as an input property: <app-svg-icon icon="yourIconName"></app-svg-icon> Make sure that you put the correct name and icon in the required folder. For size and color changes, you can add a class or an ID. Specify your rules and enjoy the result! Conclusion In this article, you have learned about a simple way of creating a shared for handling SVG icons. Remember that every application has its own specific and required application-fit solution. Hope you have found this article helpful and interesting. Angular component