uploadthing
uploadthing copied to clipboard
Add Convex adapter
This PR adds a Convex adapter as a sibling to Express, Fastify, etc. It was pretty straightforward to add a new adapter!
Here's what it looks like for wiring it in to a Convex app. First, call createUploadthing
as always:
// convex/http.ts
import { addUploadthingRoutes, convexCtx, createUploadthing, type FileRouter } from "uploadthing/convex"
import schema from "./schema"
const f = createUploadthing({
errorFormatter: (err) => {
console.log("Error uploading file", err.message);
console.log(" - Above error caused by:", err.cause);
return { message: err.message };
},
schema,
});
Note that the developer can optionally pass in their Convex schema
here for more type-safety within their handlers.
Then, define the router, using the convexCtx
function to access the request's current ctx
value. This is necessary for calling into other Convex functions, accessing auth and the database, etc. Under the hood, this uses a hack where we stash the ctx
when starting a request.
export const uploadRouter = {
imageUploader: f({ image: { maxFileSize: "4MB" } })
.middleware(async (args) => {
const ctx = convexCtx(f);
const identity = await ctx.auth.getUserIdentity();
...
return { userId: identity?.subject ?? "nothing" }
})
.onUploadComplete(async (args) => {
const ctx = convexCtx(f);
...
return { uploadedBy: args.metadata.userId };
}),
} satisfies FileRouter;
export type OurFileRouter = typeof uploadRouter;
Finally, install the routes into Convex's HTTP router with addUploadthingRoutes
:
const http = httpRouter();
addUploadthingRoutes(http, f, { router: uploadRouter })
export default http;
Questions
- The hack to sneak in
ctx
via a "global" withconvexCtx
is a bit ugly. Is there a better way to pass values to the middleware and completion callbacks? - Where should I add Convex to the docs? Would another entry next to https://docs.uploadthing.com/backend-adapters/express be the right spot?
- Should I add my Uploadthing+Convex example app from the snippets above as a new directory under
examples/
? It'll require setting up a Convex account (or self hosting Convex) to actually run the demo. - Are there any tests, etc., that I should also be updating?