며칠 삽질하고 기록🙃
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로 바꿀 예정.
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에서 완성된 글을 볼 수 있다.
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로 전환해서 구현하면 된다.
이정도면 좋은 시작이야 🐥
file add 하면 code 에서 따로 import 안해도 설치한 plugin을 쓸 수 있는건가요??