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_UPLOADTHING
totrue
. This client-side flag controls whether UploadThing features are active. -
API Key (Token/Secret): Provide your UploadThing Secret API Key in the
UPLOADTHING_TOKEN
environment 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 bycreateRouteHandler
using 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
UploadButton
generated by@uploadthing/react
(src/server/uploadthing/uploadthing.ts
). - Communicates with the
/api/uploadthing
endpoint. - 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
UploadThingUploadSingleImage
intoreact-hook-form
forms. - 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 (UTImage
model). - The
create
mutation associates the uploaded file'skey
with the authenticated user's ID. - The
delete
mutation removes the database record and usesutapi.deleteFiles(key)
(fromsrc/server/uploadthing/server.ts
) to delete the actual file from UploadThing storage. - The
UTApi
instance inserver.ts
uses theUPLOADTHING_TOKEN
for server-side actions.
Why store image metadata in our database?
Storing a reference (
key
,userId
, etc.) to the uploaded image in our ownUTImage
table 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
User
record). - 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
UTImage
table 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):