DEV Community

Stefanos Kouroupis
Stefanos Kouroupis

Posted on • Edited on

Angular: Using custom made SVG icons through Angular Material

This is a tiny, but useful post that will demonstrate how to create a service that registers custom svg icons in order to use them through the mat-icon component.

Step 1. I place all my icons under assets/svg/icons
Step 2. I create an string enum with all the icon names i.e. (you could just have a string array but I like the idea of using an enum)

export enum Icons {
    Close = 'close',
    Done = 'done',
    Edit = 'edit'
}

Step 3. I create my service. Which simply iterates all values in my string enum and registers them again the MatIconRegistry. bypassSecurityTrustResourceUrl simply bypass the security checks and trusts the svg file (make sure the svgs are to be trusted).

@Injectable({
  providedIn: 'root'
})
export class IconService {

  constructor(
    private matIconRegistry: MatIconRegistry,
    private domSanitizer: DomSanitizer
  ) { }

  public registerIcons(): void {
    this.loadIcons(Object.values(Icons), '../assets/svg/icons');
  }

  private loadIcons(iconKeys: string[], iconUrl: string): void {
    iconKeys.forEach(key => {
      this.matIconRegistry.addSvgIcon(key, this.domSanitizer.bypassSecurityTrustResourceUrl(`${iconUrl}/${key}.svg`));
    });
  }
}

Step 4. Then simply on the app.component.ts ngOnInit call the registerIcons function

  constructor(private iconService: IconService) {
  }

  ngOnInit() {
    this.iconService.registerIcons();
  }

Step 5. Use them anywhere in the application

    <mat-icon svgIcon="edit"></mat-icon>

Top comments (9)

Collapse
 
shivenigma profile image
Vignesh M

Thanks for the guide. It worked great. I have another question about coloring the icons. I know we can color SVG using CSS fill property. But when I try it is not happening.

The path inside SVG has its own fill set to a different color. The CSS color only works if I remove the fill from that path. I thought the SVG spec says that CSS color will override SVG's. Or should I strip the color info from SVG before using it?

Collapse
 
alovega profile image
alovega

Were you able to achieve this functionality?

Collapse
 
shivenigma profile image
Vignesh M

Yes. I had to override the fill color on each path, circle with CSS.

Collapse
 
florianleitgeb profile image
Florian Leitgeb

But this would load ALL icons at once, right? Also for lazy loaded modules?

Collapse
 
elasticrash profile image
Stefanos Kouroupis

No, this service registers the icons, it doesn't load any of them, until the view ultimately requests for one.

But yes, it registers all icons regardless if they are used or not.
and its quite easy to see that, if you create an interceptor and log all requests going through it, you will see requests on the svg files only when the view requests them.

Collapse
 
florianleitgeb profile image
Florian Leitgeb

What side effects does the registration have?
I am concerned about loading times and registration should not have a lot of impact to it. It feels somewhat wrong to register them globally and not only per lazy loaded module.

Thread Thread
 
elasticrash profile image
Stefanos Kouroupis

I don't think there is match of an impact since the only thing that addSvgIcon does is add an entry on a Map Object.

github.com/angular/components/blob...

You can always create a method that registers icons on demand. Personally, I don't think you will gain much by doing that, apart from over complicating your solution.

Collapse
 
vankadn profile image
Krishna

Hello Stefanos, nice article

I am having trouble to use custom icons, when I follow step you provided, it is making a request like this: localhost:4201/icon/repair.svg
and giving 404 response

Collapse
 
elasticrash profile image
Stefanos Kouroupis

well first of all the icons by default are supposed to be located under assets, except if you have a custom configuration under angular.json, which defines your assets under a different folder.

the assets (icons in this place need to be referenced from the place they are being accessed)