UploadThing: File Upload Vocabulary for Next.js Engineers
Learn the essential English terms for UploadThing file uploads in Next.js — FileRouter, middleware, onUploadComplete, and file type constraints — for ESL developers.
UploadThing is a file upload service designed specifically for TypeScript and Next.js applications. It handles storage, CDN delivery, and upload validation while giving you a type-safe API that fits naturally into a React project. If your team uses UploadThing or you are evaluating it as an alternative to storing files in S3 yourself, the vocabulary in this post will help you read its documentation and discuss file handling decisions in English.
Router and Configuration
FileRouter — the central configuration object in UploadThing where you declare all the upload routes your application supports, each with its own file type constraints, size limits, and middleware.
“We defined three entries in the FileRouter: one for profile avatars, one for post cover images, and one for PDF document uploads.”
createUploadthing — the factory function you call to initialise UploadThing and create the f helper used inside the FileRouter to define individual upload routes.
“The first line of our upload route file calls createUploadthing() to get the f helper that each route definition uses to declare its accepted file types.”
file route — a single named entry inside the FileRouter that describes one category of upload, including the accepted MIME types, maximum file size, and the maximum number of files per upload.
“The avatarUpload file route accepts only JPEG and PNG images up to 4 MB, while the documentUpload route accepts PDFs up to 16 MB.”
Middleware and Metadata
middleware — an async function attached to a file route that runs on the server before the upload is authorised; it receives the incoming request and can reject unauthorised uploads or attach metadata to the upload session.
“The middleware on the document upload route reads the session cookie and throws an UploadThingError if the user is not logged in, preventing unauthenticated uploads.”
metadata — an object returned from the middleware function that UploadThing attaches to the upload session and later passes to the onUploadComplete callback; it typically contains the user ID or other context.
“We return the current user’s ID as metadata from the middleware so the onUploadComplete callback knows which user to associate the new file URL with.”
File Type Constraints
file type constraint — a declaration in a file route specifying which MIME types or UploadThing shorthand categories (such as "image", "video", or "pdf") are accepted; files that do not match are rejected before upload begins.
“We set the file type constraint to accept only image and video categories so users cannot accidentally upload executable files through the media picker.”
maxFileSize — a property on a file route that sets the largest allowed file in a human-readable format such as "8MB" or "1GB"; UploadThing enforces this limit on the client before the upload starts.
“After users complained about slow uploads, we reduced the maxFileSize on the cover image route from 16MB to 4MB and added a client-side compression step.”
maxFileCount — a property on a file route that limits how many files a single upload request may contain; useful for gallery or attachment features where multiple files can be selected at once.
“The attachment route sets maxFileCount to 5 so users can upload up to five files per support ticket without the request timing out.”
Client-Side Hooks and Completion
useUploadThing — the React hook that connects a component to a specific file route in the FileRouter, returning an upload function, progress state, and error information.
“We call useUploadThing with the name of the avatarUpload route so the profile picture component has a type-safe upload function with automatic progress tracking.”
onUploadComplete — a server-side callback function you define on each file route; UploadThing calls it after a file has been successfully stored, passing the file URL, metadata, and file information.
“The onUploadComplete callback for the document route saves the file URL and the user ID from metadata into the database so the file appears in the user’s document library.”
upload progress — the percentage of the file that has been transferred to UploadThing’s servers; the useUploadThing hook exposes this as a reactive value you can display in a progress bar.
“We bind the upload progress value to the width of a CSS progress bar so users get clear visual feedback during large file uploads.”
Practice
Create a Next.js API route using UploadThing’s createRouteHandler and define a FileRouter with one file route for image uploads. Add middleware that checks for a logged-in user. In English, explain to a colleague what the onUploadComplete callback is responsible for and why storing the file URL in your own database is important even though UploadThing hosts the file.
Navigating Feedback Loops – A Practical Perspective
Let’s say you’re working with a junior developer, Anya, who’s recently joined your team using UploadThing. During the review of a new PR that integrates UploadThing into your Next.js application’s FileRouter middleware, she uses phrasing that feels slightly imprecise or lacks the nuance expected in professional English. You notice her saying things like, “It should handle all those file types,” rather than clearly stating requirements and expectations around validation. Or perhaps, “If it doesn’t upload, we need to investigate immediately.” These aren’t incorrect statements, but they lack the precision needed for effective communication within a development workflow.
The key here is understanding how native English speakers frame discussions about technical challenges and desired outcomes. Often, there’s an unspoken assumption of shared understanding – a level of detail that’s crucial to avoid ambiguity. A more robust approach would be something like: “Let’s ensure the middleware comprehensively validates all supported file types against the configured constraints. We need to document exactly which extensions are permitted and any associated error handling we might implement if a non-compliant file is received.” This emphasizes clarity, accountability, and proactive risk mitigation. Similarly, instead of demanding immediate action when an upload fails, you could say: “Let’s log this failure with detailed metadata – file name, type, the specific error message from UploadThing – to facilitate debugging. We can then triage it based on severity and impact.”
The goal isn’t to correct Anya directly (though gentle feedback is always welcome), but to equip her with the vocabulary she needs to articulate requirements, document decisions, and participate effectively in code reviews and discussions. It’s about moving beyond simply stating what needs to happen to describing how it should be done, including expectations for error handling and validation strategies – all crucial aspects of robust file upload management. This level of detail is not just good practice; it’s essential for reducing the likelihood of unexpected behavior and facilitating smoother collaboration within a development team. Furthermore, consistent use of precise language builds a shared vocabulary around technical concepts, preventing misunderstandings down the line.
Here’s an example of how Anya might use FileRouter to specify file type constraints:
# Example using FileRouter config (simplified for illustration)
{
"fileTypes": [
{"name": "pdf", "allowedExtensions": ["pdf"]},
{"name": "docx", "allowedExtensions": ["doc", "docx"]}
]
}
This demonstrates a clear definition of permitted file types, allowing the middleware to enforce those rules during upload. This level of detail is vital for building a reliable and maintainable system.