All tutorials with adding svg to a component in AngularCli that I found recommend to insert it in html template, something like this:
<div>
<svg viewBox="0 0 250 250">
<svg:g class="group">
<svg:polygon class="shield" points="125,30 125,30 125,30 31.9,63.2 46.1,186.3 125,230 125,230 125,230 203.9,186.3 218.1,63.2" />
<svg:path class="a" d="M125,52.1L66.8,182.6h0h21.7h0l11.7-29.2h49.4l11.7,29.2h0h21.7h0L125,52.1L125,52.1L125,52.1L125,52.1
L125,52.1z M142,135.4H108l17-40.9L142,135.4z"/>
</svg:g>
</svg>
</div>
But I wish to keep templates clear and instert only few tags in it with url to separated svg file, somwehow like this:
<svg class="star">
<use xlink:href="../../../assets/images/svg/star.svg"
x="0"
y="0" />
</svg>
Ho do I use separated svg files in components?
Importing SVG files as React Components in TypeScript svg files as React Components in a TypeScript project. import React from "react"; import { ReactComponent as SVGIcon } from "~/icons/icon.
You can use SVG files as templates in your Angular applications. When you use an SVG as the template, you are able to use directives and bindings just like with HTML templates.
Include your SVG files in src/assets folder and add the svg folder in your angular.json
file.
"assets": [ "src/assets/svg/*" ]
This way you can include the file in your components as you wish.
If you have logo.svg
:
src/assets
folderangular.json
config: "assets": [ "src/assets" ]
<img src="assets/svg/logo.svg">
HttpClient
to fetch for the file, then use bypassSecurityTrustHtml
to render it with [innerHTML]
.This may be a bit late for an answer, but here's how we found the solution. we tried looking up into how angular material does it for their icons, and boy were we surprised to how simple it really is. They were just fetching the file using HttpClient
! It was already at the back of our minds but we kept ignoring it cause we thought maybe there was a better solution.
So after a few minutes of searching, we stumbled upon this: https://github.com/angular/components/blob/653457eaf48faab99227f37bc2fe104d9f308787/src/material/icon/icon-registry.ts#L621
So basically, if you have your SVG file somewhere in your assets folder (/assets/images/svg/star.svg
), all you have to do is to fetch it using HttpClient.get
and use the DomSanitizer
to bypass security and trust the given value to be safe HTML before you can render it to your component.
And finally, here's how our component looks like:
import { Component, OnInit, SecurityContext } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { DomSanitizer } from '@angular/platform-browser';
@Component({
selector: 'app-svg-icon',
template: `<span [innerHTML]="svgIcon"></span>`,
styleUrls: ['./svg-icon.component.scss'],
})
export class SvgIconComponent implements OnInit {
@Input()
public name?: string;
public svgIcon: any;
constructor(
private httpClient: HttpClient,
private sanitizer: DomSanitizer,
) {
}
public ngOnInit(): void {
this.httpClient
.get(`assets/images/svg/${this.name}.svg`, { responseType: 'text' })
.subscribe(value => {
this.svgIcon = this.sanitizer.bypassSecurityTrustHtml(value);
});
}
}
Now you can just import the component anywhere in your app as
<app-svg-icon name="star"></app-svg-icon>
one way to do this is to set id property for your svg file and put your svg files in your asset folder. then use that id in mat-icon like this:
<mat-icon svgIcon="my-star-icon"></mat-icon>
this is a better way to do it; in this way you don't have to deal with svg tags in your UI html code. also this supports google icons.
though this works if you're using angular material.
Edit: You need to register the icon with the IconRegistry in your component for this to work:
constructor(iconRegistry: MatIconRegistry, sanitizer: DomSanitizer) {
iconRegistry.addSvgIcon(
'my-star-icon',
sanitizer.bypassSecurityTrustResourceUrl('assets/icons/my-star-icon.svg'));
}
Check the docs here and an example here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With