0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ファイルストレージサービスである【UploadThing】でNext.jsから画像をアップロードする方法

Last updated at Posted at 2025-04-15

ファイルストレージサービス【UploadThing】とは?

image.png

「uploadthing」とは、オープンソースのファイルストレージサービスです。
画像を簡単にアップローすることに特化したサービスで、Next.jsや``Nuxt.jsと親和性が高いです。

公式サイト↓

公式サイトを見ても分かるように無料プランがついており、2GBまで画像をアップローできます。

image.png

今回は、Next.jsを使って画像をアップロードする機能を作っていきます。

完成イメージ

「Choose File」ボタンをクリックしてエクスプローラを開きます。

image.png

ファイルをアップロード中はLoadingが走り、完了するとメッセージが表示されます。

image.png

その後、画像がサムネイルとしてアップされます。

image.png

ダッシュボードを見ると、先ほどの画像がアップされています。

image.png

事前準備

NPMを使ってUploadThingパッケージをインストールします。

npm i uploadthing

Uploadthingのバージョンを確認すること

Uploadthingは、バージョンによって前まで使っていた関数がサポートされていないことがあります。
なので、あらかじめバージョンの確認をしておきましょう。

この記事では、2025年4月16日時点の最新バージョンを使います。

NPMでのバージョンの確認コマンドはこちら↓

npm list uplodthing

Yarnでのバージョンの確認コマンドはこちら↓

yarn list uplodthing

.envファイルの作成と追加

Next.jsではデフォルトでは.envファイルが無いので作成します。
プロジェクトルートの直下に.envファイルを作成します。

.env
UPLOADTHING_TOKEN='your API Token'

2025年4月16日時点では、UPLOADTHING-TOKENのAPIキーのみです。
なので、.envファイルには、UPLOADTHING-TOKENの情報を入れます。

UPLOADTHING-TOKENの記載場所は、ダッシュボードにあります。↓

image.png

以上で事前準備は完了です。

Next.jsで実装

さて、いよいよ実装に入っていきます。

ディレクトリ構成

.
└── Procject/
    └── app/
        ├── api/
        │   └── uploadthing/
        │       ├── core.ts
        │       └── route.ts
        └── components/
            └── thumbnailsUploadthing/
                └── page.tsx

まずは、画面の実装からです。
Uploadthingにアップロードした画像のURLをブラウザに返却して表示するためにuseStateを使って状態管理をします。
サムネイルっぽくなるように画像を円形に処理します。

Project/app/components/thumbnailsUploadthing/page.tsx
"use client";
 
// You need to import our styles for the button to look right. Best to import in the root /layout.tsx but this is fine
import "@uploadthing/react/styles.css";
 
import { UploadButton } from "@uploadthing/react";
//import { OurFileRouter } from "./api/uploadthing/core";
import { OurFileRouter } from "@/app/api/uploadthing/core";
import { useState } from "react";
 
export default function Home() {
  const [file,setFile] = useState<string | null>(null);
  return (
    <main className="flex min-h-screen flex-col items-center justify-between p-24">
        <div className="w-full border border-gray-500 rounded-md px-8 py-4">
            <h2 className="flex justify-center font-bold">Please upload your thumbnail.</h2>
            
            {file && (
                <div className="flex justify-center mt-4 mb-4">
                    <img
                        className="w-100 h-100 rounded-full border border-gray-500"
                        alt="rounded-avator" 
                        src={file}
                    />
                </div>
            )}
            
            <UploadButton<OurFileRouter>
                endpoint="imageUploader"
                onClientUploadComplete={(res) => {
                // Do something with the response
                console.log("Files: ", res);
                setFile(res[0].url);
                alert("Upload Completed");
                }}
                onUploadError={(error: Error) => {
                // Do something with the error.
                alert(`ERROR! ${error.message}`);
                }}
            />
        </div>
    </main>
  );
}

つづいて、サーバ側の実装です。
app/api/直下にUploadthingとデータのやり取りをするための処理core.tsroute.tsを作ります。

core.tsでは、createUploadthingのインスタンスを生成します。

core.ts
const f = createUploadthing();

全体のコードはこちら↓

Project/app/api/uploadthing/core.ts
// app/api/uploadthing/core.ts
import { createUploadthing, type FileRouter } from "uploadthing/next";

const f = createUploadthing();

const auth = (req: Request) => ({ id: "fakeId" }); // Fake auth function

export const ourFileRouter = {
  imageUploader: f({ image: { maxFileSize: "4MB" } })
    .middleware(async (req) => {
      const user = await auth(req);
      if (!user) throw new Error("Unauthorized");
      return { userId: user.id };
    })
    .onUploadComplete(async ({ metadata, file }) => {
      console.log("Upload complete for userId:", metadata.userId);
      console.log("file url", file.url);
    }),
} satisfies FileRouter;

export type OurFileRouter = typeof ourFileRouter;

さいごにroute.tsです。
uploadthing@5.xのバージョン以降は、createNextRouteHandlerのインポート先が変更になっています。

route.ts
import { createRouteHandler } from "uploadthing/next";

全体のコードはこちら↓

Project/app/api/uploadthing/route.ts
/** app/api/uploadthing/route.ts */
import { ourFileRouter } from "./core";
import { createRouteHandler } from "uploadthing/next";//import { createNextRouteHandler } from "uploadthing/next";


export const { GET, POST } = createRouteHandler({
  router: ourFileRouter,
});

以上で画像がアップローできるようになります。

参考サイト

■Next.js 14 + Uploadthing : Image Preview and Delete From Server | EzyCode

SVGファイルのダウンロードとオンライン圧縮サイト

■World Vector Logo

■Image Smaller

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?