This guide explains how to migrate your existing local image and audio files to UploadThing hosting.
- UploadThing Account: Sign up at https://uploadthing.com
- Get Your Credentials:
- Go to your UploadThing dashboard
- Copy your
UPLOADTHING_TOKENandUPLOADTHING_APP_NAME
-
Add Environment Variables: Add these to your
.env.localfile:UPLOADTHING_TOKEN=your_token_here UPLOADTHING_APP_NAME=your_app_name_here
-
Verify Setup:
npm run test-uploadthing
The backfill script will:
- Find all database entries with local image/audio files
- Upload those files to UploadThing via your Next.js API
- Update the database with UploadThing URLs
- Preserve original local files for backup
Important: The dev server must be running during backfill!
-
Start the development server:
npm run dev
-
In a new terminal, run the backfill:
npm run backfill-uploadthing
The backfill script uploads files through your Next.js API route (
/api/uploadthing) to ensure proper authentication and routing.
- Images served from
/public/images/filename.jpg→http://localhost:3000/images/filename.jpg - Audio served from
/public/audio/filename.mp3→http://localhost:3000/audio/filename.mp3 - Database metadata:
{ imageFile: "filename.jpg" }
- Images served from UploadThing →
https://utfs.io/f/abc123def456.jpg - Audio served from UploadThing →
https://utfs.io/f/xyz789abc123.mp3 - Database metadata:
{ imageFile: "filename.jpg", imageUrl: "https://utfs.io/f/..." }
- The app checks for
imageUrl/audioUrlfirst - Falls back to local files if UploadThing URL not available
- No existing functionality breaks
The backfill script provides detailed logging:
🖼️ Starting image backfill...
Found 15 image files
Processing 12 entries with local images
📤 Uploading image1.jpg...
📤 Starting upload for image1.jpg (245KB)
📡 Got presigned URL, uploading to S3...
✅ Upload complete: https://utfs.io/f/abc123def456
✅ image1.jpg -> https://utfs.io/f/abc123def456
- Non-destructive: Original files remain in
/public/imagesand/public/audio - Error handling: Skips files that fail to upload, continues with others
- Rate limiting: 500ms delay between uploads to avoid overwhelming UploadThing
- Detailed logging: Shows exactly what's happening for each file
- Make sure
.env.localexists in your project root - Check that the environment variables are spelled correctly
- Restart your development server after adding variables
- Your token might be incorrect or expired
- Generate a new token from the UploadThing dashboard
- The file might be corrupted or in an unsupported format
- Check that the file exists in the expected directory
- The script will continue with other files
- Images: 4MB maximum
- Audio: 32MB maximum
Files exceeding these limits will be skipped with an error message.
Once the backfill is complete:
- All new uploads will go directly to UploadThing
- All existing files will be served from UploadThing
- Your app will be faster and more scalable
- You can eventually clean up local files if desired
You can check the migration success by:
- Looking at the database entries - they should have both
imageFileandimageUrlfields - Opening the app and viewing images/audio - they should load from UploadThing URLs
- Checking the browser network tab to see UploadThing domains (
utfs.io)
If you encounter issues:
- Check the detailed logs from the backfill script
- Verify your UploadThing dashboard shows the uploaded files
- Test with a small number of files first if you have many