Search code examples
htmlstringangulartypescriptanchor

Angular 5. How to dynamically add links to strings containing a certain tag. like '@'


I have a template view which looks like this

<div class="post-content">
      <p>{{ post.content }}</p>
</div>

where post.content is a type of string.

The string may or may not contain one or more @ tag which references different users. example: '@username'. I want to make this tag clickable with a link. Sort of insert it as an anchor tag:

<a>@username</a>

so far I have tried to string manipulate it manually, and inserting the anchor tag inside the string. However this just shows up as plain text in the view.

How do I go about this in Angular 5?


Solution

  • You have to use the innerHTML property to render the provided string as HTML, so instead of

    <p> {{post.content}} </p>
    

    You should use

    <p [innerHTML]="post.content"></p>
    

    Demo

    However, this method is not safe and is prone to XSS if not handled properly,


    The recommended method: Create a pipe with DOM Sanitization

    linkify.pipe.ts

    import { Pipe, PipeTransform } from '@angular/core';
    import { DomSanitizer } from '@angular/platform-browser';
    
    @Pipe({
      name: 'linkify'
    })
    export class LinkifyPipe implements PipeTransform {
    
      constructor(private _domSanitizer: DomSanitizer) {}
    
      transform(value: any, args?: any): any {
        return this._domSanitizer.bypassSecurityTrustHtml(this.stylize(value));
      }
    
      // Modify this method according to your custom logic
      private stylize(text: string): string {
        let stylizedText: string = '';
        if (text && text.length > 0) {
          for (let t of text.split(" ")) {
            if (t.startsWith("@") && t.length>1)
              stylizedText += `<a href="#${t.substring(1)}">${t}</a> `;
            else
              stylizedText += t + " ";
          }
          return stylizedText;
        }
        else return text;
      }
    
    }
    

    You can modify the stylize method according to your logic.

    Usage:

    <p [innerHTML]="sample | linkify"></p>
    

    Demo Stackblitz