Search code examples
angularangular-fontawesome

How to show a dynamically inserted fontawesome icon in template through innerHTML?


I am looking for a way to display text (markdown) on page that can contain a fontawesome icon. The framework is Angular 15 and fortawesome 6 has been used.

The text is dynamically inserted through an innerHTML tag. Through a markdown pipe I was able to convert the text (in markdown) to semantically correct HTML. Unfortunately, regarding the parse of the icons, I have not found a good solution for the moment. What I don't understand is, how do I prevent ng/security#xss from cleaning up my code and simultaneously have the icon placeholder convert to call the fontawesome component and display it?

I tried using

content.replace(/{!!icon!!}/g, '<fa-icon [icon]="faCoffee"></fa-icon>')

to replace the placeholder {!!icon!!} with the icon. However, Angular's security intervenes and kills the <fa-icon [icon]="faCoffee"></fa-icon>. So I attempted to use return this.domSanitizer.bypassSecurityTrustHtml in pipe to prevent the ng/security#xss from killing my code. This works but the icon is not displayed because the code <fa-icon [icon]="faCoffee"></fa-icon> is not interpreted.

@Pipe({
  name: 'sanitizer'
})
export class SanitizerPipe implements PipeTransform {

  constructor(private domSanitizer: DomSanitizer) { }

  transform(content: string, ...args: unknown[]): unknown {
      return this.domSanitizer.bypassSecurityTrustHtml(this.iconParser(content)) as SafeHtml;
    }
  }

  private iconParser = (content: string) => {
    return content.replace(/{!!icon!!}/g, `<fa-icon [icon]="faCoffee"></fa-icon>`);
  }

}

I saw a question asked quite some time ago they had solved by injecting the fontawesome component. So my approach is easily wrong, however I have no idea how I could solve it with this.

Angular's unnecessarily complicated "documentation"(API), says nothing on this topic, as usual.


Solution

  • This particular problem is solved directly by Fontawesome through this guide. The library (angular-fontawesome) provides the function icon(). This solves the problem as you just need to do:

    import { icon } from '@fortawesome/fontawesome-svg-core';
    
    ...
    
    private iconParser = (content: string) => {
      return content.replace(/{!!icon!!}/g, `${icon(faCoffee).html.join('')}`);
    }
    

    The icon(faCoffee).html.join('') code generates a valid SVG:

    <svg aria-hidden="true" focusable="false" ... ><path fill="currentColor" ...></path></svg>