Next.js App에 CKEditor5 적용하기

타임머신금지·2022년 12월 18일
1

Next.js+CKEditor5

목록 보기
1/1

며칠 삽질하고 기록🙃

Next.js 프로젝트에 WYSIWYG(위지윅) 에디터를 적용하기 위해서는 대부분 dynamic import를 사용하여 패키지를 동적으로 가져와야 한다. Next.js는 SSR를 포함하여 서버에서 또는 빌드 시에 앱의 일부를 렌더링할 수 있는데, 이 과정에서 아직 클라이언트에서 정의되지 않은 구성들을 사용할 수 있기 때문이다.

우선 CKEditor5를 Next.js를 완벽하게 지원하지 않기 때문에 다양한 툴바와 플러그인을 커스텀하여 사용하려면 online builder를 이용하여 직접 폴더를 다운로드하여 적용해야 한다.

공식 사이트에서 원하는 기능들을 골라서 선택한 후 (⚠premium 확인⚠) 빌드를 다운로드하여 프로젝트 최상단에 ckeditor5 폴더로 옮겨준 후

npm install file:./ckeditor5

로 설치를 진행한다. 그럼 내가 커스텀한 에디터를 이제 import 할 수 있다.

이후 에디터 컴포넌트 사용을 위해 남은 설치를 하자.

npm install --save @ckeditor/ckeditor5-react

공식문서
에 나와있어서 참고했다.
(사실 구글링을 먼저 했는데 공식문서를 꼼꼼히 읽는게 더 도움이 된거 같다 하지만 영어라 읽기 귀찮)

내가 필요한 주요 기능들은

  • 글정렬
  • 이미지 업로드와 사이즈 조절
  • 영상 업로드와 미리보기 재생 가능
  • 제목

그 외 글씨체, 글씨 크기, 글씨 색상, 구분선, 표 등등 무료로 제공하는 기능들을 읽어보고 다 추가해봤다.

이미지 업로드 방식에는 무료와 유료 버전이 있는데
무료에는 Base64 upload adapter와 Simple upload adapter가 있다.

지금은 Next.js에서 내가 원하는 기능을 사용할 수 있는지 테스트 해보는 단계였기 때문에 base64 형식의 업로드를 구현했다.
=> 이미지를 base64 형태로 업로드 할 경우 용량 문제로 큰 사이즈 또는 여러장의 이미지는 올릴 수 없게 된다.

추후 simple adapter로 바꿀 예정.

Editor.js

import React, { useState } from 'react';
import { CKEditor } from '@ckeditor/ckeditor5-react';
import ClassicEditor from 'ckeditor5-custom-build/build/ckeditor';

function Editor({ onClick, editorLoaded, name, value }) {
  const [test, setTest] = useState('');

  return (
    <div>
      {editorLoaded ? (
        <CKEditor
          type=""
          name={name}
          editor={ClassicEditor}
          data={value}
          onChange={(event, editor) => {
            const data = editor.getData();
            setTest(data);
          }}
          config={{
            mediaEmbed: {
              previewsInData: true,
            },
          }}
        />
      ) : (
        <div>Editor loading</div>
      )}
      <button onClick={() => onClick(test)}>전송</button>
    </div>
  );
}

export default Editor;

나는 링크로 영상을 삽입하고 preview로 재생할 수 있는 기능이 중요했기 때문에
mediaEmbed.previewsInData 설정을 true로 했다. (공식문서에 나와있음)

에디터로 작성한 결과를 getData로 얻을 수 있고 html 형식이다.
그래서 의도한대로 나오는지 테스트할 수 있도록 전송 버튼 클릭 시
resultView에서 완성된 글을 볼 수 있다.

index.js

import React, { useState, useEffect, useRef } from 'react';
import dynamic from 'next/dynamic';

export default function Home() {
  const Editor = dynamic(() => import('../components/Editor'), { ssr: false });
  const [editorLoaded, setEditorLoaded] = useState(false);
  const resultView = useRef(null);

  const onClick = (str) => {
    if (resultView.current) {
      resultView.current.innerHTML = `<h2>html결과 view입니다</h2>${str}`;
    }
  };
  useEffect(() => {
    setEditorLoaded(true);
  }, []);

  return (
    <div className="App">
      <h1>ckEditor 5</h1>
      <Editor
        name="description"
        onClick={onClick}
        editorLoaded={editorLoaded}
      />
      <div ref={resultView} />
    </div>
  );
}

적용하고 보니 CKEditor5가 기능이 많긴 하다.
React quill, toast-ui editor 등 다른 위지윅 에디터를 알아봤는데 확실히 무료라고 해도 유용한 기능이 많다. UI는 toast-ui editor가 맘에 들었는데 영상 업로드 기능도 없고 이미지 크기 조절 기능도 없어서 탈락.

이미지 업로드 기능만 서버 만들고 simple adapter로 전환해서 구현하면 된다.
이정도면 좋은 시작이야 🐥

1개의 댓글

comment-user-thumbnail
2023년 2월 6일

file add 하면 code 에서 따로 import 안해도 설치한 plugin을 쓸 수 있는건가요??

답글 달기