프로젝트에 에디터를 넣고 싶었다. 에디터를 넣고 싶어서 프로젝트 초반부터 장소 리뷰에 에디터 기능을 넣어 봤으나 팀 회의 끝에 여러가지 이유로 에디터를 도입하는 것은 적절하지 않다는 결론이 나와서 결국 폐기 되었다.
그렇게 공용 컴포넌트 폴더 한켠에서 쓸쓸하게 용도를 잃고 먼지만 쌓여가던 TuiEditor.tsx
와 TuiViewer.tsx
파일만 보면 다른 일을 하다가도 마음 한켠이 쓰려오던 것이었다.
그러다 드디어 다시 에디터를 활용해볼 기회가 왔다. 프로젝트에 게시판 기능이 생긴 것이다. 이제 게시판 글들을 에디터화 시킬 때가 왔다.
꽤 오래동안 TUI를 게시판에 적용해 보려고 애를 썼으나 결국 모든 시도가 실패로 돌아갔다. 일단 에디터 컴포넌트에 onChange 속성으로 내용의 변화를 기록하는 것 까지는 성공했으나 autofocus
속성이 끝까지 문제가 되었다.
autofocus 가 켜져있으면 같은 페이지에 있는 다른 input의 값을 수정하는것이 불가능했다. 제목같은걸 수정하려고 시도하면 해당 value state가 바뀌면서 리렌더링이 되었고 리렌더링이 되는 순간 마우스 커서가 자동으로 tui 에디터로 옮겨가 버렸기 때문이다.
반대로 autofocus를 끄면 이번에는 에디터를 수정하는것이 불가능한 문제가 발생했다. 에디터의 내용이 변할때마다 마찬가지로 리렌더링이 되는데 리렌더링이 될 때마다 focus 를 잃어버렸기 때문이다.
결국 고심 끝에 TUI 를 포기하고 다른 에디터 라이브러리를 사용하기로 결정했다.
그래서 이번에 선택한 것이 QUILL 이다.
Quill 을 선택한 이유는 다음과 같다.
- 비교적 최근까지 업데이트가 꾸준히 이어지고 있다
- 한글입력에 문제가 없다
- toolbar 커스터마이징이 자유롭다
- 리액트에서 사용 가능하다
- 참고할만 레퍼런스가 많다!
- WYSIWYG 방식이다.
quill 을 프로젝트에 적용해 보려고 했을때도 TUI를 처음 적용하려고 했을때와 같은 에러메시지가 출력되었다.
quill 도 tui 에디터와 마찬가지로 document
객체를 요구하기 때문인데 이 에러는 next/dynamic 에서 dynamic
을 임포트하고 ssr 을 막아서 해결하였다.
tui에디터에는 tui viewer가 따로 있어서 당연히 quill 에도 viewer가 있을줄 알았는데 없다는 것을 뒤늦게 알게 되었다. 그럼 내용을 표시할 때는 어떻게 하는건지 찾아보았더니 크게 두가지 방법이 있는 것으로 파악되었다.
첫번째 방식은 dangerouslySetInnerHTML
을 사용하는 방식이다.
<div
id='boardcontent'
dangerouslySetInnerHTML={{ __html: post.content }}
/>
이렇게 적게 되면 태그들이 그대로 적혀있는 quill 에디터의 내용이 해당 div 의 innerhtml 로 들어가게 된다. 하지만 이름에서 암시하듯 이 방법은 보안상 취약점이 존재한다. 바로 XSS(cross site script) 공격을 당할 위험이 있다는 것.
XSS 란?
XSS(크로스 사이트 스크립팅)는 웹 애플리케이션에서 발생하는 보안 취약점 중 하나로, 악의적인 사용자가 웹 페이지에 악성 스크립트를 삽입하여 다른 사용자들의 브라우저에서 실행되게 하는 공격입니다. 이로써 공격자는 사용자의 정보를 탈취하거나 세션을 탈취하여 불법으로 계정에 접근할 수 있습니다. -GPT3.5
또한 이런 보안 리스크를 감수한다고 하더라도 또 다른 문제도 있다. 바로 프로젝트 전체에 적용되어 있는 reset.css 때문에 기껏 에디터까지 써가면서 표현하고자 하는 style 들이 제대로 표현되지 않는다는 것.
quill 에서 내용을 표현하는 두번째 방식은 quill 에디터에 표현을 하되 에디터의 입력 기능과 toolbar를 비활성화 해서 마치 disabled된 textarea처럼 사용하는 것이다. 이번 프로젝트에서는 이 두번째 방식을 사용하기로 결정했다.
실제 적용모습과 코드는 내일 이어서 정리하기로 한다.