영원히 흘러가는 강

S3 presigned url을 통한 사진 업로드 react-quill+Nextjs 1 본문

카테고리 없음

S3 presigned url을 통한 사진 업로드 react-quill+Nextjs 1

double_R_one_G 2024. 6. 27. 12:19
728x90
내가 하고싶은것!

- 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 등록과 방법에 대해 설명해보고자 한다.

728x90
Comments