From 0 to production tutorial help with uploadthing implementation - UploadButton stuck on loading

So I am following Theo's guide to learn nextjs and react a bit, coming from sveltekit, but I am having an issue where the UploadButton component from uploadthing is stuck on loading instead of showing 'choose file' like in theo's video. The button is imported from ~/utils/uploadthing where I have the import code for it and it's not showing me any errors in VScode, but on the server I get this error which I assume is the issue "Warning: Only plain objects can be passed to Client Components from Server Components. URL objects are not supported. <... endpoint=... url={URL}>" I passed imageUploader as an endpoint like in the tutorial <UploadButton endpoint="imageUploader" /> and in the uploadthing docs, so I am not sure what I am doing wrong, any help would be appreciated and if more info is needed just let me know.
4 Replies
Ayoub K
Ayoub K4mo ago
can you provide paste both your component and server code ?
Ace
AceOP4mo ago
For sure - thanks for helping me look into it import { generateUploadButton, generateUploadDropzone, } from "@uploadthing/react"; import type { OurFileRouter } from "~/app/api/uploadthing/core"; export const UploadButton = generateUploadButton<OurFileRouter>(); export const UploadDropzone = generateUploadDropzone<OurFileRouter>(); core.ts import { createUploadthing, type FileRouter } from "uploadthing/next"; import { UploadThingError } from "uploadthing/server"; const f = createUploadthing(); const auth = (req: Request) => ({ id: "fakeId" }); // Fake auth function // FileRouter for your app, can contain multiple FileRoutes export const ourFileRouter = { // Define as many FileRoutes as you like, each with a unique routeSlug imageUploader: f({ image: { maxFileSize: "4MB" } }) // Set permissions and file types for this FileRoute .middleware(async ({ req }) => { // This code runs on your server before upload const user = auth(req); // If you throw, the user will not be able to upload if (!user) throw new UploadThingError("Unauthorized"); // Whatever is returned here is accessible in onUploadComplete as metadata return { userId: user.id }; }) .onUploadComplete(async ({ metadata, file }) => { // This code RUNS ON YOUR SERVER after upload console.log("Upload complete for userId:", metadata.userId); console.log("file url", file.url); // !!! Whatever is returned here is sent to the clientside onClientUploadComplete callback return { uploadedBy: metadata.userId }; }), } satisfies FileRouter; export type OurFileRouter = typeof ourFileRouter; Let me know if I missed something or you need something else?
Ayoub K
Ayoub K4mo ago
Provide the code where you actually render the button.
Ace
AceOP4mo ago
import { SignedIn, SignedOut, SignInButton, UserButton } from "@clerk/nextjs"; import { UploadButton } from "~/utils/uploadthing"; import { UpdatePrefs } from "./updateprefs"; export function TopNav() { return ( <nav className="flex items-center justify-between flex-wrap bg-slate-600 p-6 w-full text-white text-xl font-semibold border-b border-slate-400"> <div>Gallery</div> <div className="flex flex-row "> <SignedOut> <SignInButton /> </SignedOut> <SignedIn> <UploadButton endpoint="imageUploader"></UploadButton> <UserButton /> <UpdatePrefs /> </SignedIn> </div> </nav> ); } Just this
Want results from more Discord servers?
Add your server