angularsvgsvg-sprite

Blank icons (SVG sprite) in Angular 8


I've generated SVG spite using icomoon, to provide soft usability I've created a component for it, and realized that this is well enough practice until this time. Some icons just become blank. And I'm still can't find a reason which causes such behavior. I've investigated all issues on Stack Overflow (and not only) and did not find any solution that solves my issue.

I have symbol-defs.svg prefetching in the index.html (size of symbol-defs.svg ~ 200kb):

<link rel="prefetch" href="assets/icon/symbol-defs.svg" as="image" /> 

As a result, I've got this:

enter image description here

Empty space for most of the icons.

Icon component:

@Component({
  selector: 'icon',
  templateUrl: './icon.component.html',
  changeDetection: ChangeDetectionStrategy.OnPush,
})
export class IconComponent {
  @Input()
  set icon(icon: string) {
    this.use = icon ? `${this.location}#${icon}` : '';
  }

  use: string;
  location: string = 'assets/icon/symbol-defs.svg';
}

Icon components HTML:

<svg>
  <use [attr.xlink:href]="use" [attr.href]="use"></use>
</svg>

Usage:

<icon icon="finance-service"></icon>

UPDATES:

This issue appears only in prod mode on dev mode it performs well.


Solution

  • The reason why such behavior appears was not detected. I've deeply learned the situation and had tried a massive amount of solutions to find a gap location. The only thing that moved the things from the dead point, but completely not solves the issue, was to ad ChangeDetection.markForCheck() in icon.component. I'm pretty sure the bigger project you have the closer you are to this issue (my situation is a huge enterprise, and this issue became extremely critical since almost all icons are gone).

    Solutions that won't work for you (with such sprite approach):

    Prefetching symbol-defs.svg with any kind of approaches, by using link rel="prefetch" or by preloading it with angular APP_INITIALIZER approach.

    The solution that will solve the issue (but still won't bring the answer on the previous question) is:

    Place your SVG sprite in the top of the index.html before closing tag </head, remove location string from the icon component. The profits you've got are - minus 1 request, clear/stable usability.