How to Use Custom SVG Icons in Angular Material

WeiHung Chin

The Angular Material library offers a suite of Angular components styled with Material Design. One such component is the <mat-icon> component. There are a wide range of ready-made Material icons which we can use readily. But what if we want to display some custom icons while staying consistent with the Material Design styling? Let’s learn how to use our own SVG icons in Angular Material components.

This post assumes you have some basic knowledge of Angular v4.2+. The Angular version used in this example is v5.2+ and the angular material version is v5.2.4.

The first part of this post introduces the setup steps required to display the default material icons. If you’re already familiar with this, head directly to the Custom SVG Icons section.

You can refer to this post if you're just getting started with Angular Material.

Installation

Firstly, in your Angular project, install Angular Material and its dependencies with the command below:

$ npm install --save @angular/material @angular/cdk @angular/animations hammerjs

# or, using yarn:
$ yarn add @angular/material @angular/cdk @angular/animations hammerjs

Material Icons

In order to use the default Material icons, you’ll need to import them in the global stylesheet. To do this, open the style.css file generated by the Angular CLI and add the following import statement at the top:

style.css

@import url("https://fonts.googleapis.com/icon?family=Material+Icons");

/* other css */

Then import MatIconModule and add it to your module’s imports:

app.module.ts

import { MatIconModule } from "@angular/material/icon";

@NgModule({
  declarations: [
    AppComponent,
    ...
  ],
  imports: [
    ...
    MatIconModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Now, you can use the built-in material icons with the <mat-icon> component like so:

app.component.html

<mat-icon>mood</mat-icon>

A full list of Material icons which you can use directly can be found here.

Custom SVG Icons

Let’s say you have a custom icon, unicorn_icon.svg placed in the assets folder of your project. Here’s an example folder structure:

- src
- assets
  - unicorn_icon.svg
- environments
- index.html
- ...

The app structure above is the default structure scaffolded using the Angular CLI.

To use our custom 🦄 icon with the <mat-icon> component tag, we’ll need to add HttpClientModule to our component module’s imports as Angular Material needs this:

app.module.ts

import { MatIconModule } from "@angular/material/icon";
import { HttpClientModule } from "@angular/common/http";

@NgModule({
  declarations: [
    AppComponent,
    ...
  ],
  imports: [
    ...
    MatIconModule,
    HttpClientModule
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Then we can register our custom icon with the MatIconRegistry service provided by Angular Material.

Import the MatIconRegistry and inject the service into your component. In the component’s constructor method, invoke the addSvgIcon method like so:

app.component.ts

import { Component } from "@angular/core";
import { MatIconRegistry } from "@angular/material/icon";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent{
  constructor(private matIconRegistry: MatIconRegistry){
    this.matIconRegistry.addSvgIcon(
      `icon_label`,
      `path_to_custom_icon.svg`
    );
  }
}

The addSvgIcon registers our icon by taking-in 2 arguments, the first one being the icon label which is of type string.

The second argument is the relative URL path pointing to the location of the icon. This is of type SafeResourceUrl. To parse the url path string into SafeResourceUrl, we can make use of the DomSanitizer provided by Angular.

Import DomSanitizer and inject it into your component

app.component.ts

import { Component } from "@angular/core";
import { MatIconRegistry } from "@angular/material/icon";
import { DomSanitizer } from "@angular/platform-browser";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"]
})
export class AppComponent{
  constructor(
    private matIconRegistry: MatIconRegistry,
    private domSanitizer: DomSanitizer
  ){
    this.matIconRegistry.addSvgIcon(
      "unicorn",
      this.domSanitizer.bypassSecurityTrustResourceUrl("../assets/unicorn_icon.svg")
    );
  }
}

Given a relative URL path string, the bypassSecurityTrustResourceUrl method on DomSanitizer will return a safe resource URL, which is required by the addSvgIcon method.

In the component’s template, to display our icon, we can then pass the icon label to the svgIcon input property of <mat-icon> like so:

app.component.html

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

You should see that the custom icon 🦄 is displayed with Material font and styling!

The full working code can be found in in this Github repo.

💪 Now you're able to display a full set of custom icons in your apps with Material styling. To make the code cleaner and more maintainable, we can refactor the code by moving the MatIconRegistry into a service class, checkout the repo link above for example code.

  Tweet It

🕵 Search Results

🔎 Searching...

Sponsored by #native_company# — Learn More
#native_title# #native_desc#
#native_cta#