# Binding HTML with Angular

Source: https://tpiros.dev/blog/binding-html-with-angular

Sometimes an API returns HTML data, or you've got HTML sitting in your code that you want to render inside a `<div>` in an Angular template.

Using the traditional double curly brace syntax won't work here. It displays the encoded version of the HTML string:

```typescript

@Component({
  selector: 'app-root',
  styleUrls: ['./app.component.css'],
  template: `<div>{{ data }}</div>`,
})

  data = `<b>This text is bold</b> and this one is <i>italics</i>`;
}
```

The above spits out the string `<b>This text is bold</b> and this one is <i>italics</i>`, which is obviously not what we want.

To display correctly formatted HTML, bind to the `div`'s `innerHTML` property:

```typescript

@Component({
  selector: 'app-root',
  styleUrls: ['./app.component.css'],
  template: `<div [innerHTML]="data"></div>`,
})

  data = `<b>This text is bold</b> and this one is <i>italics</i>`;
}
```

The above correctly yields "This text is bold and this one is italics."

> Please note that by default Angular is sanitizing the input for templates and it escapes untrusted values.

# Safe HTML

HTML data can contain malicious content. Be wary when unknown HTML needs processing. Angular ships with built-in XSS protection and a separate [DomSanitizer](https://angular.io/api/platform-browser/DomSanitizer) that helps prevent Cross-Site Scripting Security (XSS) bugs.

We can see the built-in XSS protection at work with this example:

```typescript

@Component({
  selector: 'app-root',
  styleUrls: ['./app.component.css'],
  template: `<div [innerHTML]="data"></div>`,
})

  data = `<b>This text is bold</b> and this one is <i>italics</i> <img src=x onerror='alert("hello there")'>`;
}
```

When serving the application, a warning message states 'sanitizing HTML stripped some content.' The alert never fires. Checking the source code reveals something like this:

```html
<div _ngcontent-c0="">
  <b>This text is bold</b> and this one is <i>italics</i> <img src="x" />
</div>
```

Note the `img` tag is still there but the `onerror` attribute has been stripped out.

## What if I have trusted content?

You can override the default sanitiser behaviour using the `DomSanitizer` mentioned earlier. Create a custom pipe and apply it to HTML content you know to be safe.

Here's the pipe:

```typescript

@Pipe({
  name: 'sanitizeHtml',
})

  constructor(private sanitizer: DomSanitizer) {}
  transform(value: any): any {
    return this.sanitizer.bypassSecurityTrustHtml(value);
  }
}
```

This pipe bypasses the built-in security and no longer checks the HTML input.

Apply the pipe and see the result:

```typescript

// ...
template: `<div [innerHTML]="data | sanitizeHtml"></div>`;
```

This time the `alert()` fires. Apply caution when using any of the `bypassSecurityX` methods in Angular.

### A word of caution

Don't change this default behaviour lightly. The built-in sanitiser does you a massive favour by stripping unsafe HTML content. Think long and hard about whether the HTML content can truly be trusted before bypassing it.
