앵귤러 템플릿에서 innerHTML과 DomSanitizer를 사용하는 방법
블로그 앱에서 tinymce 같은 플러그인으로 작성한 글은 HTML 코드 형태로 데이터베이스에 저장됩니다. 이 데이터를 앵귤러 템플릿에서 다시 렌더링하는 방법을 정리합니다.
데이터베이스에 저장된 HTML 코드가 아래와 같다고 가정합니다.
<h1><span style="color: #f1c40f;">안녕하세요. 이상희입니다.</span></h1>가장 흔한 실수는 아래와 같이 HTML 코드를 태그 안에 그대로 삽입하는 방식입니다.
<div class="post-content">{{ post.content }}</div>이렇게 작성하면 아래 이미지처럼 HTML 코드가 일반 텍스트로 그대로 출력됩니다.

이 문제는 아래와 같이 innerHTML 속성 바인딩(property binding)을 사용해 해결할 수 있습니다.
<div class="post-content" [innerHTML]="post.content"></div>
HTML 코드는 정상적으로 렌더링되지만 또 다른 문제가 있습니다. 개발자 도구로 실제 적용된 코드를 살펴보면 아래와 같이 span 태그에 포함되어 있던 인라인 CSS 스타일이 사라져 있습니다.

이 동작은 앵귤러가 위험한 HTML 코드의 삽입을 차단하기 위해 제공하는 기본 보호 장치 때문에 발생합니다. 신뢰 가능한 콘텐츠임을 명시해야 하며, 앵귤러가 제공하는 DomSanitizer 클래스로 간단히 처리할 수 있습니다.
먼저 템플릿에서 사용할 파이프 클래스를 생성합니다.
$ ng g pipe trust-htmltrust-html.pipe.ts가 생성되면 아래와 같이 수정합니다.
import { Pipe, PipeTransform } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
@Pipe({
name: 'trustHtml'
})
export class TrustHtmlPipe implements PipeTransform {
constructor(private sanitizer: DomSanitizer) {
}
transform(content): unknown {
return this.sanitizer.bypassSecurityTrustHtml(content);
}
}app.module.ts의 declarations에 등록하는 것도 잊지 말아야 합니다.
import { TrustHtmlPipe } from './pipes/trust-html.pipe';
@NgModule({
declarations: [
AppComponent,
... 생략 ...
TrustHtmlPipe,
],생성한 파이프를 템플릿에서 사용하면 다음과 같습니다.
<div class="post-content" [innerHTML]="post.content | trustHtml"></div>
이상으로 innerHTML 속성 바인딩과 파이프(pipe) 클래스를 활용해 데이터베이스에 저장된 HTML을 앵귤러 템플릿에서 안전하게 렌더링하는 방법을 정리했습니다.