How to inject SVG icon sprites in Angular component HTML DOM?

angular svg-icon npm
angular svg component
could not find httpclient provider for use with angular material icons
angular 5 svg component
svg sprite
install angular svg icon
error retrieving icon: unable to find icon with the name
import angularsvgiconmodule from angular svg icon

I am building an Angular application (Angular 4/5/6) and would like to use SVG sprites in my component template.

Question: Assuming I already have my SVG icon sprite generated (icons.svg), how can I get Angular to inject/import my SVG icon sprite into my component's template?

Is there a way to inject/import my SVG icon sprite into my component without having to use any 3rd party modules/directives and do it natively with Angular itself?

Background/Issue:

As discussed in this article, icons.svg file would contain all the SVG icons defined as <symbol>. Then I can render selected icons in my HTML using <use> assuming the icons.svg is injected in the DOM.

I generated SVG sprites using IcoMoon app, and saved the icons.svg into my Angular application. Below is my sample Angular component (app.component.ts) in which I am trying to inject/import the icons.svg file and trying to render the SVG icons in my HTML. However, Angular is not rending my SVG icons. I seems I am incorrectly injecting the SVG icon sprite file.

Updates:

  1. I am already aware of a similar question, SVG icon system with angular-cli, where the suggested answer was to use the Node module svg-sprite to generate a SVG sprites using the CSS mode. However, this is NOT what I am asking. I am NOT trying to generate the SVG sprites. I am trying get Angular components to be aware of my SVG sprite, icons.svg, and get it to render them in the HTML whenever I make use of them.
  2. A solution was suggested,https://stackoverflow.com/a/50460361/4988010, to generate a CSS font from the SVG sprite. I feel this is NOT a feasible solution and instead is a "workaround" to not being able to use the SVG sprite.

app.component.ts: Live example on StackBlitz: https://stackblitz.com/edit/angular-bbr2kh?file=src/app/app.component.ts

import { Component } from '@angular/core';
// import `./icons.svg`; // This import method doesn't work


@Component({
  selector: 'my-app',
  template: `

   <!-- This import method doesn't work -->
   <!-- <script src="./icons.svg"></script>  -->

  <p>
  Hello this is a sample Angular 6 component.
  </p>

  <p>Testing to see if SVG icon sprite import works. See below if icons appear. </p>
  <p>Icon (home): <svg class="icon icon-home"><use xlink:href="#icon-home"></use></svg> </p>
  <p>Icon (rocket): <svg class="icon icon-rocket"><use xlink:href="#icon-rocket"></use></svg> </p>
  <p>Icon (wifi): <svg class="icon icon-connection"><use xlink:href="#icon-connection"></use></svg>

  <!-- This import method doesn't work -->
  <!-- <p>Icon (home): <svg class="icon icon-home"><use xlink:href="./icons.svg#icon-home"></use></svg> </p>-->

   </p>
  `,
  styles: [`

  .icon {
  display: inline-block;
  width: 1em;
  height: 1em;
  stroke-width: 0;
  stroke: currentColor;
  fill: currentColor;
  }

  `]
})
export class AppComponent {
}

I think your root path is where you are having problems. In your code you are telling angular to look in app but the browser sees this as https://your-site.com./icons

If you move your icon file under your /assets folder, then it should be available already because the src\assets folder is already included in angular.json, the "assets" collection tells Angular where to look.

<svg class="icon">
   <use xlink:href="/assets/icons.svg#icon-rocket"></use> // Notice root path not "./"
</svg>

If you would like your files to be served from another directory all you need to do is add a path in your angular.json:

…
"assets": [
   "src/favicon.ico",
   "src/assets",
   "src/your-dir"
],
…

Then in your code

<svg class="icon">
   <use xlink:href="/your-dir/icons.svg#icon-rocket"></use>
</svg>

I wouldn't suggest adding /src/app as an asset path, this would basically open up your entire app for serving files, making your entire directory accessible.

I forked your example and updated here

Icon System with SVG Sprites, A nice way to handle your icons is to have a folder full of .svg files. #Inject that SVG at the top of the document. Literally include it, like: <!DOCTYPE html> <html lang="en"> <head> . Browsers treat <use> like the shadow DOM: You can use styles to target the icon as a whole, but not individual components within it; the  I am unsure if this is a a bug or I am not using Angular properly. But after many attempts, I think Angular is unable to inject/import a file into my component's HTML template. Issue/Question. I am trying to inject/import a SVG icon sprites file (icons.svg) into my component's template. Despite various ways of importing the sprite file, none of

you can convert your svg file to font by https://icomoon.io/app/#/select, upload your svg file and select it,click on the Generate Font then click the download button, download font file and choose font folder and put it in a folder in your project,

import font file into css files

@font-face {
   font-family: 'icomoon';
   src:  url('fonts/icomoon.eot?31svmk');
   src:  url('fonts/icomoon.eot?31svmk#iefix') format('embedded-opentype'),
   url('fonts/icomoon.ttf?31svmk') format('truetype'),
   url('fonts/icomoon.woff?31svmk') format('woff'),
   url('fonts/icomoon.svg?31svmk#icomoon') format('svg');
  font-weight: normal;
  font-style: normal;
}

declear your class like this

.icon-home:before {
  content: "\ea77";
}
.icon-conection:before {
  content: "\ea78";
}
.icon-rocket:before {
 content: "\ea79";
}

and use it in your html

  <p>Icon (rocket): <i class="icon-rocket"></i> </p>

The solution was to add the icons in the project, but if you want to use the svg code in the project, it's best to add the loader to it.

If you have used the webpack:

  npm install svg-inline-loader --save-dev

Simply add configuration object to module.loaders like this.

{
    test: /\.svg$/,
    loader: 'svg-inline-loader'
}

more info

Angular svg sprite, We're not joking. html - Inject that SVG at the top of the document by SVG icon sprite component for Angular 8. html) You probably want to use your It is explicitly designed to work with other web standards such as CSS, DOM, and SMIL. You can use your own svg sprite as well as used material design icons. You need to provide the svg sprite file in component and are good to go. The source code of the above example is also available at github: SVG-ICONS-Ang-4. Important Links. Angular: https://angular.io; Angular material: https://material.angular.io; Mat Icon Overview: https

I was in your same boat today with designers pushing back about the svg font. I also did not want to move the icon def out of the node_modules because it would change over time. I came up with a solution.

You need to first create an angular icon component, then do something like this:

import { Component, OnInit, Input } from '@angular/core';
declare const require;
@Component({
  selector: 'my-icon',
  templateUrl: './my-icon.component.html',
  styleUrls: ['./my-icon.component.scss']
})
export class IconComponent implements OnInit {

  constructor() { }

  @Input() icon: string = "";
  @Input() x: string = "0";
  @Input() y: string = "0";
  @Input() fillColor: string = "black";
  @Input() strokeColor: string = "black";
  @Input() height: string = "";
  @Input() width: string = "";
  private baseUrl: string = require("../../../../../node_modules/path/to/defs.svg") + "#beginning-of-iconset-";

  svgUrl: string = "";

  ngOnInit() {
  }

  ngAfterViewInit() {
    setTimeout(()=>{
      this.svgUrl = this.baseUrl + this.icon;
    },0);

  }

}

And then, in the html:

<svg [attr.height]="height" [attr.width]="width" xmlns="http://www.w3.org/2000/svg">
  <use [attr.href]="svgUrl" [attr.x]="x" [attr.y]="y" [attr.fill]="fillColor" [attr.stroke]="strokeColor" />
</svg>

I'm still working on scaling the solution as the width and height attributes don't work as expected. You can also expand on the inputs as I know I will.

Hope that helps.

Creating SVG Icon Components And SVG Icon Sprites In Angular 7.2.0, Creating SVG Icon Components And SVG Icon Sprites In Angular 7.2.0 To demonstrate what the rendered HTML looks like without [title]. This "svg" element is automatically injected by the "svg-sprite-loader" for Webpack. This appears to be a key challenge to overcome, trying to use inline or external svg sprites. External or Inline use? We support IE11 (which has no support for external SVG), so we initially considered using the inline method. With it, you inject your master svg symbols sprite into the top of your html files, and reference them later by ID.

I solved this issue using angular material icon.

Angular material injects the SVG by id and without shadow-dom.

first install angular material:

"@angular/material": "^7.3.7", // change version according to your angular version 

Import to your module:

MatIconModule

Then declare your SVG sprite in the app.component or service..

    constructor(
        private matIconRegistry: MatIconRegistry,
        private domSanitizer: DomSanitizer) { 
matIconRegistry.addSvgIconSet(this.domSanitizer.bypassSecurityTrustResourceUrl(`assets/sprite.svg`));
        }

And last, In Html use angular material icon:

<mat-icon svgIcon="svg-id"></mat-icon> // or use as directive <div svgIcon="svg-id"></div>

Read more here

How to Use Custom SVG Icons in Angular Material ← Alligator.io, A quick guide on how to use your own SVG icons with Angular Material 2. src - assets - unicorn_icon.svg - environments - index.html - The app structure above is Import DomSanitizer and inject it into your component. 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.

Component based SVG Icon System, Much has been written about SVG Icon Systems and why they are is on front-​end JavaScript frameworks such as React, Angular, Vue.js, etc. then generates the sprite sheet and injects it into DOM on run-time. Injected sprite sheet URL to use for resolving all the relative URLs in an HTML document. Add angular-svg-icons dependency to your module angular . module ( ' app ' , [ ' angular-svg-icons ' ]); Configure the component with the path of the svg sprites file and the folder of individual svg

Angular svg sprite, Simple SVG icon component for Angular 2+ to use SVG icons from SVG sprite. It will briefly How to inject SVG icon sprites in Angular component HTML DOM? Angular: Dynamically inserting SVG into an element By Chris Mendez On June 17, 2017 - 4 min read I was recently asked to make a single-page web app for a digital illustrator.

Can you use both internal and external SVG sprites in icon systems , Our main applications are using Angular 2 and it's Router. src/index.html') .pipe​(inject(gulp.src('icons-sprite.svg'), { starttag: '<! Basically, because polymer components inject things as shadowy DOM, the browser doesn't  (svg-definitions.component.html) You probably want to use your SVG icons on different pages, so you need to be sure that definitions are loaded everywhere in the app.To do this we will load svg-definitions.component in the main component.

Comments
  • Create a my-icon component that takes a reference to your sprite sheet for @input. Check this... Stackblitz
  • If I am using icons from SVG sprite on multiple screens, then it will be a separate network call for the sprite to render individual icon, isn't it? Is there a way to restrict this call to once on application boot up?
  • @parthsw If you want to load all the sprites on load, I would keep all the sprites in one file this article explains it fairly well, in short you add all the sprites as symbols in one svg file then use it like <svg><use xlink:href="assets/svgSprites.svg#spriteID"></use></svg>
  • Its great to know that I can convert my SVG sprites to fonts, however, I don't think this is feasible solution. Why can't I directly use the SVG sprites itself? Why do I have to circumvent around the main issue?
  • I already had this problem and I had to use this solution, this method fixes your problem. Unless you have another reason to use svg in Angular
  • If you use WebPack, you may be able to fix your problem by adding a loader , I add the explanation in the above text. i hope it can help you
  • I don't know understand why we have to use a "CSS/Font" workaround instead of being able to directly use SVG. Is this a bug in Angular? Is Angular not flexibility enough to support basic features such as being able to load external files?
  • @AlirezaVarmaghani while creating production build it's directly adding file to the root of it (svgs and fonts). It should directly imported into CSS itself.