ファイルストレージサービス【UploadThing】とは?
「uploadthing」とは、オープンソースのファイルストレージサービスです。
画像を簡単にアップローすることに特化したサービスで、Next.jsや``Nuxt.js
と親和性が高いです。
公式サイト↓
公式サイトを見ても分かるように無料プランがついており、2GBまで画像をアップローできます。
今回は、Next.js
を使って画像をアップロードする機能を作っていきます。
完成イメージ
「Choose File」ボタンをクリックしてエクスプローラを開きます。
ファイルをアップロード中はLoadingが走り、完了するとメッセージが表示されます。
その後、画像がサムネイルとしてアップされます。
ダッシュボードを見ると、先ほどの画像がアップされています。
事前準備
NPMを使ってUploadThingパッケージをインストールします。
npm i uploadthing
Uploadthingのバージョンを確認すること
Uploadthingは、バージョンによって前まで使っていた関数がサポートされていないことがあります。
なので、あらかじめバージョンの確認をしておきましょう。
この記事では、2025年4月16日時点の最新バージョンを使います。
NPMでのバージョンの確認コマンドはこちら↓
npm list uplodthing
Yarnでのバージョンの確認コマンドはこちら↓
yarn list uplodthing
.env
ファイルの作成と追加
Next.js
ではデフォルトでは.env
ファイルが無いので作成します。
プロジェクトルートの直下に.env
ファイルを作成します。
UPLOADTHING_TOKEN='your API Token'
2025年4月16日時点では、UPLOADTHING-TOKEN
のAPIキーのみです。
なので、.env
ファイルには、UPLOADTHING-TOKEN
の情報を入れます。
UPLOADTHING-TOKEN
の記載場所は、ダッシュボードにあります。↓
以上で事前準備は完了です。
Next.jsで実装
さて、いよいよ実装に入っていきます。
ディレクトリ構成
.
└── Procject/
└── app/
├── api/
│ └── uploadthing/
│ ├── core.ts
│ └── route.ts
└── components/
└── thumbnailsUploadthing/
└── page.tsx
まずは、画面の実装からです。
Uploadthingにアップロードした画像のURLをブラウザに返却して表示するためにuseState
を使って状態管理をします。
サムネイルっぽくなるように画像を円形に処理します。
"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.ts
とroute.ts
を作ります。
core.ts
では、createUploadthing
のインスタンスを生成します。
const f = createUploadthing();
全体のコードはこちら↓
// 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
のインポート先が変更になっています。
import { createRouteHandler } from "uploadthing/next";
全体のコードはこちら↓
/** 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