[Trend-Now] Custom Blot으로 img Blot에 id 속성 추가하기(Quill 라이브러리)

강수영·2025년 9월 2일
0

🚨 문제 상황

저는 Quill 에디터에서 커스텀 이미지 핸들러를 구현해, 이미지를 S3에 업로드한 뒤 서버로부터 이미지 URL과 ID를 전달받았습니다.

백엔드에서 이미지를 효율적으로 관리하려면 실제로 글에서 사용되는 이미지의 ID만 전달해야 했기 때문에, 최종 제출 시점에서 전체 데이터(Delta)를 순회해 현재 에디터에 남아 있는 이미지들의 ID만 추출해 서버에 전달하려고 했습니다.

하지만 기본 이미지 삽입은 단순히 url만 설정할 수 있고, ID 값은 삽입할 수 없었습니다.

💡 해결: Custom Blot 구현하기

Custom Blot을 구현해 Quill의 img Blot 에 data-id 속성을 넣을 수 있도록 했습니다.

아래 코드처럼 구현하면 이미지 삽입 시 urlid를 함께 넣을 수 있고, 컨텐츠(Delta)에도 두 값이 기록됩니다.

import Quill from 'quill';
import { BlockEmbed } from 'quill/blots/block';

// 커스텀 이미지 블롯 정의
class CustomImageBlot extends BlockEmbed {
  static blotName = 'customImage'; // 델타에서 사용할 블롯 이름
  static tagName = 'img'; // 실제 DOM에 삽입될 태그 (img 태그 사용)

  // 에디터에 이미지 삽입할 때 호출되는 메서드
  static create(value: { id: string; url: string }) {
    const node = super.create() as HTMLElement; // 기본 img 요소 생성
    node.setAttribute('src', value.url); // 이미지 URL 설정
    node.setAttribute('data-id', value.id); // 추가 식별자(data-id) 설정
    return node; // 최종 img 노드 반환
  }

  // 에디터로부터 델타(Delta)를 생성할 때 사용되는 메서드
  static value(node: HTMLElement) {
    return {
      id: node.getAttribute('data-id'), // data-id 값을 델타에 포함
      url: node.getAttribute('src'), // src 값을 델타에 포함
    };
  }
}

// 이미 같은 이름의 포맷이 등록되어 있는지 확인하고, 없다면 등록
if (!Quill.imports['formats/customImage']) {
  Quill.register(CustomImageBlot); // 커스텀 이미지 블롯을 Quill에 등록
}

🔄 Delta를 HTML로 변환할 때 Custom Blot 적용하기

게시물 내용을 보여줄 때는 quill-delta-to-html 라이브러리를 사용해 Delta를 HTML로 변환했습니다.

하지만 Custom Blot을 사용했기 때문에 기본 변환만으로는 부족했고, 추가 작업이 필요했습니다.

const delta = JSON.parse(post.content);
const converter = new QuillDeltaToHtmlConverter(delta.ops);

converter.renderCustomWith((customOp) => {
  if (customOp.insert.type === 'customImage') {
    const { id, url } = customOp.insert.value;
    return `<img src="${url}" data-id="${id}" />`;
  }
  return '';
});

const html = converter.convert();

return <div dangerouslySetInnerHTML={{ __html: html }} />;

이처럼 renderCustomWith를 사용해 customImage<img src="..." data-id="..."> 형태로 직접 변환하도록 처리했습니다.

🚀 결과

Custom Blot을 이용해 이미지의 urlid를 함께 관리할 수 있게 되었고, 최종 제출 시 올바른 ID 값을 서버에 전달하여 백엔드에서 이미지를 효율적으로 관리할 수 있게 되었습니다.

또한 DeltaHTML 변환 과정에서도 Custom Blot을 대응하도록 구현해, 이미지가 <img src="..." data-id="..."> 형태로 정상적으로 렌더링되도록 처리했습니다.

출처

profile
프론트엔드 개발자

0개의 댓글