Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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 {
}
like image 255
Zythyr Avatar asked May 22 '18 03:05

Zythyr


People also ask

How do I link an SVG to a sprite in HTML?

SVG Sprite Stacks The <use> element is a little long-winded and can only be used within an <svg> (either a standalone image or embedded within HTML). It can't be used in an <img> , <iframe> , <object> , or as a CSS background. The method works in all browsers including Internet Explorer 9 and above.

How do I use custom SVG icons in HTML?

SVG images can be written directly into the HTML document using the <svg> </svg> tag. To do this, open the SVG image in VS code or your preferred IDE, copy the code, and paste it inside the <body> element in your HTML document. If you did everything correctly, your webpage should look exactly like the demo below.

How do I use SVG sprites?

To create a sprite in SVG we use the <symbol> tag and apply an ID for referencing later and the viewBox attribute for defining the canvas size. Inside of the symbol icon we create our shapes, text and any other elements that make up our icon.


1 Answers

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

like image 88
Andy Braham Avatar answered Sep 20 '22 01:09

Andy Braham