영원히 흘러가는 강
S3 presigned url을 통한 사진 업로드 react-quill+Nextjs 1 본문
내가 하고싶은것!
- react-quill을 이용하여 이미지 등록시에 presigned url을 이용하여 이미지를 미리 등록한다.
- react-quill value에는 위에 등록한 주소를 넣어 하나의 필드로 저장한다.
많은 에디터 라이브러리가 있지만 가장 대중적으로 많이 사용되는 react-quill을 이용하여 내 프로젝트의 상세페이지를 구성해보려한다.
내 환경은 제목에서처럼 react + react-quill + Next.js + drf 이다.
위에서처럼 내가 하고싶은것 의 첫번째가 react-quill을 Next.js에 적용하는 사항이다보니
이번편에서는 react-quill / Next.js를 많이 다룰 예정이다.
react-quill은 시작부터 오류를 뿜어내준다 ..ㅎ
import ReactQuill from react-quill
Quill은 ssr 지원이 되지 않아 static하게 import를 해오면
document is not defined
이와같은 에러를 맞이하게 된다.
document를 정의하기도 전에 react-quill이 로드되어 document를 조작하려해서 발생하는 에러이다.
해결 방법은
import dynamic from 'next/dynamic'
const ReactQuill = dynamic(()=>import("react-quill"),{ssr:false});
dynamic-import를 사용해서 브라우저에서만 작동하게 가져오는것이다.
ssr은 false로 두어 documnet 문제를 해결한다.
그다음으로 공식문서를 참조한다면 css 파일을 참조하라고한다.
기본 테마의 css이니 추가해준다.
import "react-quill/dist/quill.snow.css";
이렇게 해서 완료된다면 좋겠지만...
엄청난 삽질과 자존감을 갉아먹는 시간으로 빠진다...
가장 중요한 이미지 등록의 문제이다...
가장 기본의 포맷에는 이미지 등록 등 많은 사항들이 빠져있다.
모듈과 포맷을 작성해줘야 가능한데 아래는 나의 모듈과 포맷이다.
* 모듈은 useMemo로 감싸줘야하는데
useMemo를 사용하지 않는다면 변경될때마다 모듈을 새로만들어 포커스를 벗어난다.
const formats = [
"header","font","size","bold","italic","underline","strike","align","blockquote",
"list","bullet","indent","background","color","link","image","video","width",
];
const modules = useMemo(
() => ({
toolbar: {
container: [
["link", "image", "video"],
[{ header: [1, 2, 3, false] }],
["bold", "italic", "underline", "strike"],
["blockquote"],
[{ list: "ordered" }, { list: "bullet" }],
],
handlers: {
image: imageHandler, //이미지 등록시 imageHandler 구현 필요
},
},
}),
[]
);
그 다음 위에서 작성한 imageHandler 함수에 대한 작성이 필요하다.
아래는 내가 작성한 imageHandler이다.
const imageHandler = async () => {
const input = document.createElement("input"); //input을 생성
input.setAttribute("type", "file");
input.setAttribute("accept", "image/*");
input.click(); // input 클릭 효과
input.onchange = async () => {
const files = input.files;
if (files && files.length > 0) {
const file = files[0];
if (file) {
try {
const uploadeUrl = await handlePresignedUrl(file); //2편에서 설명
if (!uploadeUrl) {
throw new Error("이미지 업로드 URL을 가져올 수 없습니다.");
}
const uploadedUrl = await handleImageUpload(uploadeUrl, file); //2편에서 설명
const quill = quillRef?.current?.getEditor();
if (quill) {
const range = quill.getSelection(true);
quill.insertEmbed(range.index, "image", uploadedUrl);
quill.setSelection(range.index + 1);
}
} catch (error) {
if (error instanceof Error) {
alert(error?.message);
}
}
}
}
};
};
이와같이 작성하면 react-quill 완성!
내가하고싶은것의 첫번째
react-quill을 이용하여 이미지 등록시에 presigned url을 이용하여 이미지를 미리 등록한다.
'react-quill을 이용하여 이미지 등록' 까지 완성이다...
다음편에 계속해서 presigned url 등록과 방법에 대해 설명해보고자 한다.