8주차 - uploadthing

ggomadev·2024년 8월 25일
0

Ultimate Next.js Course

목록 보기
7/7
post-thumbnail

uploadthing

파일 업로드 기능을 간편하게 구현할 수 있도록 도와주는 라이브러리 (공식문서)
Github 계정으로 가입하고, API KEY를 받아 문서에 나온대로 하면 간단하게 파일 업로드 기능을 구현할 수 있다. 프로젝트에서는 설정 메뉴에서 계정 이미지를 수정하는 기능에 사용했다.


npm install uploadthing @uploadthing/react
// .env.local
UPLOADTHING_SECRET=추가1
PLOADTHING_APP_ID=추가2

app > api 폴더 내부에 uploadthing 폴더 생성
uploadthing 폴더 내부에 core.ts, route.ts 파일을 추가한다.
upload.ts는 uploadthing 라이브러리에서 제공하는 UploadButton을 넣었다.

  • core.ts
import { createUploadthing, type FileRouter } from "uploadthing/next";
import { UploadThingError } from "uploadthing/server";

const f = createUploadthing();

export const ourFileRouter = {
  // 공식 문서에는 middleware가 있는데, 현 프로젝트의 경우 불필요하여 제거
  avatarUploader: f({ image: { maxFileSize: "2MB" } }).onUploadComplete(
    async ({ metadata, file }) => {}
  ),
} satisfies FileRouter;

export type OurFileRouter = typeof ourFileRouter;
  • route.ts
import { createRouteHandler } from "uploadthing/next";
import { ourFileRouter } from "./core";

export const { GET, POST } = createRouteHandler({
  router: ourFileRouter,
});
  • upload.ts
import {
  generateUploadButton,
  generateUploadDropzone,
} from "@uploadthing/react";

import type { OurFileRouter } from "./core";

export const UploadButton = generateUploadButton<OurFileRouter>();
export const UploadDropzone = generateUploadDropzone<OurFileRouter>();
  • 추가한 후에 사용하는 폼에 import해서 사용하면 된다.
return (
    <Card>
      <CardContent>
        <Form {...form}>
          <form onSubmit={form.handleSubmit(onSubmit)} className="space-y-6">
           // ... 코드코드
                   	<UploadButton
                      className="scale-75 ut-button:ring-primary ut-label:bg-red-50 ut-button:bg-primary/75 hover:ut-button:bg-primary/100 ut:button:transition-all ut-button:duration-500 ut-label:hidden ut-allowed-content:hidden"
                      endpoint="avatarUploader"
                      onUploadBegin={() => {
                        setAvatarUploading(true);
                      }}
                      onUploadError={(error) => {
                        form.setError("image", {
                          type: "validate",
                          message: error.message,
                        });

                        setAvatarUploading(false);
                        return;
                      }}
                      onClientUploadComplete={(res) => {
                        form.setValue("image", res[0].url!);
                        setAvatarUploading(false);
                        return;
                      }}
                      content={{
                        button({ ready }) {
                          if (ready) return <div>Change Avatar</div>;
                          return <div>Uploading...</div>;
                        },
                      }}
                    />
                  </div>

                  <FormControl>
                    <Input
                      placeholder="User Image"
                      type="hidden"
                      disabled={status === "executing"}
                      {...field}
                    />
                  </FormControl>
                  <FormMessage />
                </FormItem>
              )}
            />
          </form>
        </Form>
      </CardContent>
    </Card>
  );
  • tailwind.css를 사용해서 커스터마이징한다면 config 파일에 withUt를 추가해줘야 한다.
  • tailwind.config.ts
import { withUt } from "uploadthing/tw";
 
export default withUt({
  content: ["./src/**/*.{ts,tsx,mdx}"],
  ...
});
  • 파일 업로드 중일 때 디폴트 버튼의 스타일링을 바꾸고 싶다면 global.css에서 추가해주면 된다고 한다.
[data-ut-element="button"][data-state="uploading"]::after {
  @apply bg-primary/50;
}

0개의 댓글