WiniLogis는 글로벌 무역 부킹 서비스를 제공하는 플랫폼으로, 블로그를 운영하고 있습니다.
현재 블로그의 콘텐츠는 WiniLogis 관리자 사이트를 통해 관리되지만, 단순 텍스트만 입력할 수 있다는 문제가 있어 다른 플랫폼에서 운영하는 블로그에 비해 가독성이 떨어지는 문제가 있었습니다.
WiniLogis 관리자의 블로그 글 작성 시 가독성 문제를 해결하기 위해, 텍스트 에디터를 도입하여 글을 편집할 수 있도록 개선한 방법에 대해 작성하려고 합니다.
먼저 React 프로젝트와 잘 어울리는 텍스트 에디터를 찾기 위해 여러 정보를 조사했습니다. 아래 글을 통해 다양한 텍스트 에디터의 종류를 확인하고, 각 에디터의 장단점을 비교하여 최종적으로 적용할 에디터를 결정했습니다.
https://code-b.dev/blog/rich-text-editors-react
Development Guides, Comparing Tech Stacks, Frameworks & More
Find detailed development guides, outsourcing tips & best development practices here at Code-B's blogroom
payload-cms.code-b.dev
결론적으로 저는 React-quill을 선택했습니다.
선택한 이유는 간결한 UI와 더불어, 여러 블로그에서 확인한 결과 커스터마이징이 매우 쉽고 유연할 것이라고 판단했기 때문입니다.
WiniLogis 관리자 Code
import ReactQuill from 'react-quill';
/* react-quill style */
import 'react-quill/dist/quill.snow.css';
const modules = {
toolbar: [
[{ header: [false, 1, 2, 3] }],
[
'bold',
'italic',
'underline',
'strike',
{ color: [] },
{ background: [] },
{ align: [] },
{ list: 'ordered' },
{ list: 'bullet' },
'link',
'clean',
],
],
};
<ReactQuill
className='w-full'
placeholder='공백 포함 최대 2000자'
theme='snow'
modules={modules}
value={boardData.content}
onChange={(value) =>
setBoardData({
...boardData,
content: value,
})
}
코드에 대해서 간단히 설명드리면 onChange 이벤트가 발생할 때 에디터의 내용이 value로 반환되며, 이는 아래와 같은 HTML 형식으로 출력됩니다.
<h1>H1 글자 테스트</h1>
<p><br></p>
<h2>H2 글자 테스트</h2>
<p><br></p>
<h3>H3 글자 테스트</h3>
<p><br></p>
<p>nomal 글자 테스트</p>
<p><br></p>
<p><strong>굵게 테스트</strong></p>
<p><br></p>
<p><em>기울임 테스트</em></p>
<p><br></p>
<p><u>밑줄 테스트</u></p>
<p><br></p>
<p><s>줄 그어짐 테스트</s></p>
<p><br></p>
<p><span style="color: rgb(194, 133, 255);">글자 색 변경 테스트</span></p>
<p><br></p>
<p><span style="background-color: rgb(0, 102, 204);">글자 배경 색 테스트</span></p>
<p><br></p>
<p>좌측 정렬</p>
<p><br></p>
<p class="ql-align-center">중앙 정렬</p>
<p><br></p>
<p class="ql-align-right">우측 정렬</p>
<p class="ql-align-right"><br></p>
<p>번호 매기기 테스트</p>
<ol>
<li>테스트1</li>
<li>테스트2</li>
<li>테스트3</li>
</ol>
<p><br></p>
<p>ul 테스트</p>
<ul>
<li>li1</li>
<li>li2</li>
<li>li3</li>
</ul>
<p><br></p>
<p><a href="https://www.winilogis.com/" rel="noopener noreferrer" target="_blank">링크연동 위니로지스 테스트</a></p>
WiniLogis 관리자 구현 화면
WiniLogis 코드
import styled from 'styled-components';
import DOMPurify from 'dompurify';
interface DangerouslySetInnerHTML {
__html: string;
}
export default function DangerouslySetInnerHTML({
__html,
}: DangerouslySetInnerHTML) {
return (
<Box
dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(__html),
}}
/>
);
}
const Box = styled.div`
h1 {
font-size: 3rem;
}
h2 {
font-size: 2.5rem;
}
h3 {
font-size: 2rem;
}
strong {
font-weight: bold;
}
em {
font-style: italic;
}
.ql-align-center {
text-align: center;
}
.ql-align-right {
text-align: right;
}
ol,
ul {
padding-left: 2.5rem;
}
ol li {
list-style: decimal !important;
}
ul li {
list-style: disc !important;
}
a {
color: #000;
text-decoration: underline;
text-underline-offset: 3px;
}
a:hover {
color: #221477;
}
`;
코드에 대해서 간단히 설명 드리면 DangerouslySetInnerHTML이라는 컴포넌트로 분리하여, 관리자에서 작성한 HTML 코드를 props로 전달받아 렌더링 하는 방식으로 개발했습니다.
XSS 공격을 방어하기 위해 DOMPurify 라이브러리를 사용해 전달된 HTML을 정화(sanitize) 처리했습니다.
또한, HTML 태그별로 커스터마이징 효과를 주기 위해 Styled Components를 활용해 스타일을 적용했습니다.
WiniLogis 구현 화면
'지식 정리 📝' 카테고리의 다른 글
브라우저 언어와 크로스 브라우징 (0) | 2024.10.17 |
---|---|
S3와 CloudFront로 정적 사이트 호스팅: React 앱 배포 경험 (1) | 2024.10.08 |
자바스크립트의 이벤트 루프(Event Loop)란? (1) | 2024.09.07 |
Expo 호스팅을 통해 React Native 앱 배포하기 (0) | 2024.08.24 |
차세대 이미지 포맷(WebP)을 통한 웹 성능 개선 (0) | 2024.08.22 |