Overview
File upload with button and dropzone variants. Progress tracking and analytics built-in.
Components
Upload Button
Simple upload button.
import { UploadThingButton } from "@/components/elements/uploadthing/upload-button";
export function MyUploader() {
return (
<UploadThingButton
endpoint="imageUploader"
onUploadComplete={(files) => console.log(files)}
onUploadError={(error) => console.error(error)}
/>
);
}
Upload Dropzone
Drag-and-drop with progress.
Drop files here or click to browse
Allowed file types: image/png, image/jpeg
import { UploadThingDropzone } from "@/components/elements/uploadthing/upload-dropzone";
export function FileUploader() {
return (
<UploadThingDropzone
endpoint="imageUploader"
maxFiles={4}
onUploadComplete={(files) => console.log(files)}
/>
);
}
Setup
1. Install
npm install uploadthing @uploadthing/react
2. Get API Keys
From uploadthing.com dashboard.
3. Environment Variables
UPLOADTHING_SECRET=sk_live_...
UPLOADTHING_APP_ID=your-app-id
4. File Router
// app/elements/uploadthing/core.ts
import { createUploadthing, type FileRouter } from "uploadthing/next";
const f = createUploadthing();
export const ourFileRouter = {
imageUploader: f({ image: { maxFileSize: "4MB" } })
.onUploadComplete(({ file }) => {
console.log(file.url);
}),
} satisfies FileRouter;
export type OurFileRouter = typeof ourFileRouter;
5. API Route
// app/api/uploadthing/route.ts
import { createRouteHandler } from "uploadthing/next";
import { ourFileRouter } from "@/app/elements/uploadthing/core";
export const { GET, POST } = createRouteHandler({
router: ourFileRouter,
});
File Types
f({ image: { maxFileSize: "4MB" } })
f({ pdf: { maxFileSize: "8MB" } })
f({ video: { maxFileSize: "16MB" } })
f({ blob: { maxFileSize: "32MB" } })
Callbacks
onUploadComplete={(files) => {
files.forEach(f => console.log(f.ufsUrl));
}}
onUploadError={(error) => {
console.error(error.message);
}}
Troubleshooting
Upload fails: Check API keys and route at /api/uploadthing
File rejected: Verify type in core.ts