[Next.js] Cloudinary 를 사용한 파일 업로드 기능 구현하기

문지은·2024년 1월 22일
1

Next.js - App Router

목록 보기
11/20
post-thumbnail

Cloudinary 설정하기

  • 파일을 업로드하기 위해서는 우선 클라우드 플랫폼을 선택해야 한다.
    • Amazon Web Service, Amazon S2, Google Cloud Platform, Microsoft Azure 등 다양한 클라우드 플랫폼이 존재한다.
  • Next.js 와 완벽하게 통합할 수 있는 컴포넌트를 제공하는 Cloudinary 를 사용하여 파일 업로드 기능을 구현해보자.
    • Cloudinary는 다른 클라우드 플랫폼과 달리 별도의 코딩이 필요 없고, 간단한 구성만으로도 충분히 파일 업로드 기능을 구현할 수 있다.
  • Cloudinary 웹사이트로 이동하여 계정을 생성한다.
    • 무료로 서비스 이용이 가능하지만, 대역폭이 더 필요한 경우 추가 요금이 필요하다.
  • 회원가입이 끝나면 홈페이지가 나타나고 좌측 아래에 Production Environment 라는 탭을 볼 수 있다.
    • 여기에서는 다중 환경을 만들 수 있는데, 환경이란 쉽게 말해 하나의 애플리케이션에서 파일을 업로드할 때 사용하는 저장소라고 생각하면 된다.

  • 이를 사용하기 위해 먼저 프로젝트에 next-cloudinary 패키지를 설치한다.
    • 이 패키지는 파일 업로드 및 미리 보기 등 다양한 React 컴포넌트를 제공한다.
npm install next-cloudinary

  • 환경 변수는 Production Environment 탭에서 환경 하나를 선택하고 Node.js를 클릭했을 때 나오는 CloudName Property 값을 사용하면 된다.

.env

NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME="<Your Cloud Name>"

Cloudinary 이미지 업로드하기

  • Next Cloudinary 공식문서를 보면, 이미지 업로드 및 보기에 사용할 수 있는 다양한 컴포넌트를 확인할 수 있다.
    • 이 중에는 업로드 버튼, 업로드 위젯, 비디오 플레이어 등이 포함되어 있다.
  • 업로드 위젯을 한번 사용해보자.
    • 공식문서에서 제공하는 컴포넌트 코드를 복사해 바로 사용할 수 있다.

  • 프로젝트 진행을 위해 먼저 app 폴더 안에 upload 라는 폴더를 생성하고 페이지 파일을 생성한 후, CldUploadWidget를 추가한다.

app/upload/page.tsx

import { CldUploadWidget } from "next-cloudinary";

const UploadPage = () => {
  return (
    <CldUploadWidget uploadPreset="<YOUR UPLOAD PRESET>">

    </CldUploadWidget>
  );
};

export default UploadPage;
  • CldUploadWidget 컴포넌트를 사용하기 위해서는 uploadPreset 속성을 설정하여야 한다.
    • uploadPreset는 업로드에 적용할 설정들을 미리 정의할 수 있는 속성이다.
  • 속성 값을 가져오기 위해 Cloudinary 콘솔로 이동해 좌측 하단 settings 에 들어간다.

  • Upload 섹션에서 Add upload preset 버튼을 클릭한다.

  • 이후 새 Upload Preset 으로 Unsigned Preset 을 지정하고 이름을 복사한다.
    • Unsigned Preset 은 사용자 인증 없이 파일을 업로드할 수 있도록 허용한다는 의미이다.
      • 일반적으로 보안상의 이유로 Signed Preset 이 권장되지만, 테스트 목적으로 Unsigned Preset 을 사용하겠다.

app/upload/page.tsx

"use client";

import { CldUploadWidget } from "next-cloudinary";

const UploadPage = () => {
  return (
    <CldUploadWidget uploadPreset="jjyzftfd">
      {({ open }) => (
        <button className="btn btn-primary" onClick={() => open()}>
          Upload an Image
        </button>
      )}
    </CldUploadWidget>
  );
};

export default UploadPage;
  • 위에서 작성한 open이라는 props는 클릭 이벤트로 해당 함수가 실행되었을 때 파일을 업로드할 수 있는 인터페이스를 출력시킨다.
    • 클릭 이벤트는 클라이언트 컴포넌트만 사용할 수 있기 때문에 use client 지시문을 추가하여야 한다.
  • 이제 upload 페이지(http://localhost:3000/upload)로 이동하여 확인해보자.
    • 버튼을 클릭하면 Cloudinary 에서 제공하는 업로드 인터페이스를 확인할 수 있다.

  • 기본적으로 여러 파일을 업로드할 수 있지만 이를 비활성화하여 단일 파일을 업로드할 수도 있다.
  • 이미지를 업로드하면 미리보기 기능이 제공된다.

  • 이렇게 업로드된 파일은 Cloudinary 콘솔의 Media Library 탭에서 확인할 수 있다.

업로드한 이미지 렌더링하기

  • 이제 업로드한 이미지를 화면에 표시해보자.
  • 업로드 위젯 컴포넌트에는 파일이 업로드될 때마다 활성화되는 업로드 이벤트가 있다.
    • onUpload 함수는 이 이벤트를 수신할 수 있으며, resultwidget 두 개의 인자를 받는다.
    • onUpload 함수를 추가하고 이미지가 업로드되면 콘솔에 결과를 출력하도록 해보자.
    • 경우에 따라 콘솔을 보면 post 메시지 실행 오류가 발생할 수 있으나, 이는 일시적인 오류로 애플리케이션의 작동을 방해하지 않기 때문에 걱정하지 않아도 된다.

app/upload/page.tsx

"use client";

import { CldUploadWidget } from "next-cloudinary";

const UploadPage = () => {
  return (
    <CldUploadWidget
      uploadPreset="jjyzftfd"
      onUpload={(result, widget) => {
        console.log(result);
      }}
    >
      {({ open }) => (
        <button className="btn btn-primary" onClick={() => open()}>
          Upload an Image
        </button>
      )}
    </CldUploadWidget>
  );
};

export default UploadPage;
  • 이미지 업로드 후 콘솔에 출력되는 Result 객체에는 EventInfo 두 속성이 포함되어 있다.
    • Event는 업로드 성공을 나타내며, Info에는 이미지 크기, 생성날짜, 형식, 높이, 너비, 원본파일 이름, 사진을 고유하게 식별할 때 사용하는 Public ID 등의 정보가 담겨있다.
    • Public ID 속성을 통해 Cloudinary 이미지 컴포넌트에서 이미지를 렌더링 할 수 있다.

  • 먼저 PublicId를 저장할 상태변수를 선언하고, 이미지 업로드에 성공하면 PublicId 를 저장한다.
    • PublicId를 저장하기 위한 인터페이스 정의도 필요하다.
  • CldImage 컴포넌트에 저장한 PublicId 를 전달하여 이미지를 렌더링 한다.

app/upload/page.tsx

"use client";

import { CldUploadWidget } from "next-cloudinary";
import { CldImage } from "next-cloudinary";
import { useState } from "react";

interface CloudinaryResult {
  public_id: string;
}

const UploadPage = () => {
  const [publicId, setPublicId] = useState("");

  return (
    <div>
      {publicId && (
        <CldImage
          src={publicId}
          width={270}
          height={180}
          alt="Uploaded Image Not Found"
        />
      )}
      <CldUploadWidget
        uploadPreset="jjyzftfd"
        onUpload={(result, widget) => {
          if (result.event !== "success") return;
          const info = result.info as CloudinaryResult;
          setPublicId(info.public_id);
        }}
      >
        {({ open }) => (
          <button className="btn btn-primary" onClick={() => open()}>
            Upload an Image
          </button>
        )}
      </CldUploadWidget>
    </div>
  );
};

export default UploadPage;
  • 브라우저에서 확인해보면, 이미지 업로드에 성공했을 때 화면에 이미지가 잘 출력되는 것을 볼 수 있다.

Cloudinary 파일 업로드 위젯 커스텀하기

profile
코드로 꿈을 펼치는 개발자의 이야기, 노력과 열정이 가득한 곳 🌈

0개의 댓글