Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I import svg from file to a component in angular 5?

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?

like image 431
mr_blond Avatar asked Oct 30 '18 14:10

mr_blond


People also ask

How do I import an SVG file into TypeScript?

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.

Can we use SVG in Angular?

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.


4 Answers

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.

like image 37
Harini P Avatar answered Oct 17 '22 02:10

Harini P


If you have logo.svg:

  1. Put it inside your src/assets folder
  2. Include folder in the angular.json config: "assets": [ "src/assets" ]
  3. Refer to it from template: <img src="assets/svg/logo.svg">
like image 132
Boris Yakubchik Avatar answered Oct 17 '22 01:10

Boris Yakubchik


TL;DR, use 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>
like image 10
jsnewbie Avatar answered Oct 17 '22 01:10

jsnewbie


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.

like image 8
Arya11 Avatar answered Oct 17 '22 01:10

Arya11