Managing SVG Icons in Your Angular App
Tags: angular, javascript, svg, programming
Published: 2021-02-17 16:29:28

Preston Lamb | ng-conf | Dec 2020

### **tldr;**
In the last couple years, SVG has become the preferred way of displaying icons in web applications. This is because SVGs can be scaled to any size without loss of quality, they can be changed to any color, and they can be animated. These are just a few of the benefits. The downside is that the SVG code is a little hard to manage and deal with in your application. Luckily there are tools to help with this in your Angular apps that make using SVG icons much easier than before.

### **SVG Icons**
There are two ways to include SVG icons in your app. You can place a `.svg` image on the page, or the SVG’s XML code. The XML code is what allows you to change the display of the icon, and is my preferred way of doing it. The problem with the XML code method is that you have a big, complicated piece of XML in your HTML that doesn’t tell you what the icon is, and is prone to accidentally being changed. Here’s an example of an SVG icon:

```
<svg xmlns=”http://www.w3.org/2000/svg" viewBox=”0 0 20 20" fill=”currentColor”>
  <path d=”M10.394 2.08a1 1 0 00-.788 0l-7 3a1 1 0 000 1.84L5.25 8.051a.999.999 0 01.356-.257l4–1.714a1 1 0 
11.788 1.838L7.667 9.088l1.94.831a1 1 0 00.787 0l7–3a1 1 0 000–1.838l-7–3zM3.31 9.397L5 10.12v4.102a8.969 
8.969 0 00–1.05-.174 1 1 0 01-.89-.89 11.115 11.115 0 01.25–3.762zM9.3 16.573A9.026 9.026 0 007 14.935v-
3.957l1.818.78a3 3 0 002.364 0l5.508–2.361a11.026 11.026 0 01.25 3.762 1 1 0 01-.89.89 8.968 8.968 0 00–
5.35 2.524 1 1 0 01–1.4 0zM6 18a1 1 0 001–1v-2.065a8.935 8.935 0 00–2-.712V17a1 1 0 001 1z” />
</svg>
```

As you can see, that’s a huge piece of XML. What’s worse, you can’t tell what it does just by looking at it. And what happens if a small part of it is accidentally deleted? There’s gotta be a better way to deal with it, right? Well, lucky for us there is.

I recently discovered a library on NPM called `angular-svg-icon` that allows you to load the SVG code from above into a service and then output the icon by name in your template with an Angular element. This is the process:

```
// app.component.ts
export class AppCompnent {
  constructor(private _registry: SvgIconRegistryService) {}
  
  ngOnInit() {
    this._registry.addSvg(‘academic-cap’, ‘…SVG CODE…’);
  }
}
```

This code snippet imports the `SvgIconRegistryService` from `angular-svg-icon` and declares a new SVG icon called `academic-cap` that you can use in your template, like this:

```
<svg-icon name=”academic-cap”></svg-icon>
```

That will output the SVG onto the screen wherever you want. You can style the SVG by using the `svgClass` input:

```
<svg-icon name=”academic-cap” svgClass=”bg-red-400 h-20 w-20" ></svg-icon>
```

This method drastically improves the ease of using SVG icons in your application. But there’s one more improvement that can be made with the `angular-svg-icon-preloader` library. This library is meant to be used in conjunction with `angular-svg-icon` and will load SVG icons from a JSON file when your app bootstraps. This way you don’t need to muddy your `AppComponent` file to load several frequently-used icons. The service will just load all the icons for you automatically, and then you can use them in your templates as shown above. You can load the SVG data or SVG image files, whichever one you would prefer. Here’s how the JSON file should be created:

```
// icons.json
{
  "iconImageFiles": [
    {
      "iconName": "badge-check",
      "iconPath": "/assets/icons/badge-check.svg"
    }
  ],
  "customIcons": [
    {
      "iconName": "academic-cap",
      "iconData": "<svg xmlns=\"http://www.w3.org/2000/svg\" > <path d=\"...\" /> </svg>"
    }
  ]
}
```

There are two array attributes as part of the JSON file, `iconImageFiles` and `customIcons`. The items in these arrays both have an `iconName` attribute, and then either `iconPath`, which is a path to the SVG file for the icon, or `iconData`, which is the SVG’s XML data. When your app bootstraps, these icons will be loaded for you. Just place the JSON file somewhere in your app where it can be accessed when the app is running, like the `assets` folder, and then tell the app where it’s located when importing the `AngularSvgIconPreloaderModule`:

```
// app.module.ts
@NgModule({
  imports: [
    AngularSvgIconModule.forRoot(),
    AngularSvgIconPreloaderModule.forRoot({
      configUrl: './assets/json/icons.json',
    }),
  ]
})
```

In the `forRoot` method on the `AngularSvgIconPreloaderModule`, provide an object with a `configUrl` attribute that has the path to the icons file. That’s all it takes to have the icons preloaded for you in your app. Now, it’s not necessary to load every icon in your app through the JSON file, but at the very least you can load the most used icons. If you still want to load icons in a component with the `SvgIconRegistryService`, you can do that too.

### **Conclusion**
After discovering the `angular-svg-icon` library, dealing with SVG icons became much easier and convenient. No more random SVG data in my templates, and everyone knows exactly what icon is being used. This will definitely be a common tool in my toolbox from now on.

## **ng-conf: The Musical is coming**
ng-conf: The Musical is a two-day conference from the ng-conf folks coming on April 22nd & 23rd, 2021. Check it out at [ng-conf.org](https://www.2021.ng-conf.org/)