UploadThing Integration
How UploadThing is integrated for file uploads.
This document explains how UploadThing is integrated for handling file uploads, specifically focusing on single image uploads.
Configuration
-
Enable Switch: Set
NEXT_PUBLIC_ENABLE_UPLOADTHINGtotrue. This client-side flag controls whether UploadThing features are active. -
API Key (Token/Secret): Provide your UploadThing Secret API Key in the
UPLOADTHING_TOKENenvironment variable. -
Environment Setup:
src/config/config.ts: DefinesUPLOADTHING_URL_ROOT(used for constructing image URLs, this shouldn't be changed unless UploadThing changes something).
How it Works
-
File Router (
src/app/api/uploadthing/core.ts):- Defines the server-side logic for handling uploads using
createUploadthing. - Currently includes one route:
imageUploader, configured for single images up to 4MB. - Middleware: Contains authentication logic (
auth). onUploadComplete: Server-side callback after a successful upload. Currently logs information.
- Defines the server-side logic for handling uploads using
-
API Route (
src/app/api/uploadthing/route.ts):- Exports the Next.js App Router handlers (
GET,POST) generated bycreateRouteHandlerusing theourFileRouter.
- Exports the Next.js App Router handlers (
-
Client Upload Component (
src/components/core/UploadThingUploadSingleImage):- A reusable React component for handling the upload UI and logic for a single image.
- Uses the
UploadButtongenerated by@uploadthing/react(src/server/uploadthing/uploadthing.ts). - Communicates with the
/api/uploadthingendpoint. - Displays the uploaded image or the upload button.
- Handles upload success (
onClientUploadComplete) and errors (onUploadError). - Calls tRPC mutations (
utImage.create,utImage.delete) after successful upload or before deletion to manage database records. - Includes a delete button to remove the image.
-
Form Integration (
src/components/FormFieldUploadThingImage.tsx):- A wrapper component to easily integrate
UploadThingUploadSingleImageintoreact-hook-formforms. - Manages the form state for the image, which typically stores
{ id: string, key: string } | null.
- A wrapper component to easily integrate
-
Database & Server Actions (
src/server/api/routers/utImage.ts,src/server/uploadthing/server.ts):- A tRPC router (
utImageRouter) handles creating and deleting image records in the database (UTImagemodel). - The
createmutation associates the uploaded file'skeywith the authenticated user's ID. - The
deletemutation removes the database record and usesutapi.deleteFiles(key)(fromsrc/server/uploadthing/server.ts) to delete the actual file from UploadThing storage. - The
UTApiinstance inserver.tsuses theUPLOADTHING_TOKENfor server-side actions.
Why store image metadata in our database?
Storing a reference (
key,userId, etc.) to the uploaded image in our ownUTImagetable serves several purposes:- Association: It allows us to directly link an uploaded image to a specific user or another data model within our application (e.g., linking an avatar image key to a
Userrecord). - Ownership & Security: We can easily verify ownership before allowing actions like deletion.
- Cleanup & Orphan Prevention: By having a record in our database, we ensure that we don't lose track of images uploaded to UploadThing. This makes cleanup easier. For example, a periodic cleanup job (e.g., a cron job) could query the
UTImagetable for old or unassociated images and then call the UploadThing API (utapi.deleteFiles) to remove them, preventing orphaned files in UploadThing storage without needing to constantly list all files via the UploadThing API.
- A tRPC router (
Usage
Typically, you would use the FormFieldUploadThingImage component within a form where a user needs to upload a single image (like a profile picture or cover image):