Skip to content
WiniLogis실무 경험

Fixing WiniLogis blog readability with a React-Quill text editor

1 min readWorkMoved from my Tistory blogRead the Korean original

WiniLogis is a platform that offers booking services for global trade, and it runs a blog.

The blog content is managed through the WiniLogis admin site, but the admin only allowed plain text, so the posts were harder to read than blogs run on other platforms.

Here is how I fixed the readability of blog posts written in the WiniLogis admin by adding a text editor for editing them.

First, I researched text editors that work well with a React project. Using the articles below, I looked at the different kinds of text editors, compared the pros and cons of each, and decided which one to use.

https://code-b.dev/blog/rich-text-editors-react

In the end, I chose React-quill.

I chose it for its simple UI, and because, from what I saw on several blogs, I judged that it would be very easy and flexible to customize.

WiniLogis admin code

jsx
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,
    })
 }

To explain the code briefly: when the onChange event fires, the editor's content is returned as value, and it comes out in HTML like the following.

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>

Implemented screen in the WiniLogis admin

Implemented screen in the WiniLogis admin
Figure 1. Implemented screen in the WiniLogis admin

WiniLogis code

tsx
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;
  }
`;

To explain the code briefly: I split this out into a component called DangerouslySetInnerHTML, which receives the HTML written in the admin as props and renders it.

To defend against XSS attacks, I used the DOMPurify library to sanitize the HTML passed in.

I also used Styled Components to apply custom styles to each HTML tag.

Implemented screen on WiniLogis

Implemented screen on WiniLogis
Figure 2. Implemented screen on WiniLogis
  • #Autowini
  • #DOMPurify
  • #React
  • #react-quill
  • #WiniLogis
  • #XSS
  • #text editor
  • #frontend

More in Work