UploadButton Error: Cannot read properties of undefined (reading 'match')

I'm following the tutorial and I have an error at https://youtu.be/d5x0JCZbAJs?t=3622 for UploadButton. Any thoughts? Helpful info: I'm using the latest versions of uploadthing: dependencies: @clerk/nextjs 5.0.0-beta.46 next 14.2.15 @t3-oss/env-nextjs 0.10.1 postgres 3.4.4 @uploadthing/react 7.0.3 react 18.3.1 @vercel/postgres 0.10.0 react-dom 18.3.1 drizzle-orm 0.33.0 uploadthing 7.1.0 geist 1.3.1 zod 3.23.8 devDependencies: @types/eslint 8.56.12 @types/node 20.16.11 @types/react 18.3.11 @types/react-dom 18.3.0 @typescript-eslint/eslint-plugin 8.8.1 @typescript-eslint/parser 8.8.1 drizzle-kit 0.24.2 eslint 8.57.1 eslint-config-next 14.2.15 eslint-plugin-drizzle 0.2.3 postcss 8.4.47 prettier 3.3.3 prettier-plugin-tailwindcss 0.6.8 tailwindcss 3.4.13 typescript 5.6.3
Theo - t3․gg
YouTube
From 0 to Production - The Modern React Tutorial (RSCs, Next.js, Sh...
The Modern React Tutorial is FINALLY done. This one took awhile. Shoutout to ALL the awesome sponsors who made this possible: - Vercel - Clerk - Posthog - Sentry - Upstash NOTES I MENTION DURING VIDEO "Nextgram": https://github.com/vercel/nextgram/tree/main/app "useUploadThingInputProps": https://gist.github.com/t3dotgg/0464ca78e94acce80ba04ca...
No description
3 Replies
Vida Zing
Vida ZingOP•3mo ago
I tried to debug this. I ended up getting "Error: Cannot access uploadthing.match on the server. You cannot dot into a client module from a server component. You can only pass the imported name through." as an error. I don't know what I did to get it to start passing "^7.0.0" for the check in "function warnIfInvalidPeerDependency(pkg, required, toCheck) {" Is this error a bug or did I do something wrong? This is how I imported it
import { UploadButton } from "~/utils/uploadthing";
import { UploadButton } from "~/utils/uploadthing";
This was the example code file router.
import { auth } from "@clerk/nextjs/server";
import { createUploadthing, type FileRouter } from "uploadthing/next";
import { UploadThingError } from "uploadthing/server";

const f = createUploadthing();

// 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();

// If you throw, the user will not be able to upload
// eslint-disable-next-line @typescript-eslint/only-throw-error
if (!user.userId) throw new UploadThingError("Unauthorized");

// Whatever is returned here is accessible in onUploadComplete as `metadata`
return { userId: user.userId };
})
.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;
import { auth } from "@clerk/nextjs/server";
import { createUploadthing, type FileRouter } from "uploadthing/next";
import { UploadThingError } from "uploadthing/server";

const f = createUploadthing();

// 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();

// If you throw, the user will not be able to upload
// eslint-disable-next-line @typescript-eslint/only-throw-error
if (!user.userId) throw new UploadThingError("Unauthorized");

// Whatever is returned here is accessible in onUploadComplete as `metadata`
return { userId: user.userId };
})
.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;
I can fix this with "use client" . e.g.
"use client";

import { SignedIn, SignedOut, SignInButton, UserButton } from "@clerk/nextjs";
import { UploadButton } from "~/utils/uploadthing";

export function TopNav() {
return (
<nav className="w- front-semibold flex items-center justify-between border-b p-4 text-xl font-semibold">
<div>Gallery</div>

<div className="flex flex-row">
<SignedOut>
<SignInButton></SignInButton>
</SignedOut>
<SignedIn>
<UploadButton endpoint="imageUploader"></UploadButton>
<UserButton></UserButton>
</SignedIn>
</div>
</nav>
);
}
"use client";

import { SignedIn, SignedOut, SignInButton, UserButton } from "@clerk/nextjs";
import { UploadButton } from "~/utils/uploadthing";

export function TopNav() {
return (
<nav className="w- front-semibold flex items-center justify-between border-b p-4 text-xl font-semibold">
<div>Gallery</div>

<div className="flex flex-row">
<SignedOut>
<SignInButton></SignInButton>
</SignedOut>
<SignedIn>
<UploadButton endpoint="imageUploader"></UploadButton>
<UserButton></UserButton>
</SignedIn>
</div>
</nav>
);
}
Vida Zing
Vida ZingOP•3mo ago
Oh I see this change is made a few minutes later in the video 😢 https://youtu.be/d5x0JCZbAJs?t=3774
Theo - t3․gg
YouTube
From 0 to Production - The Modern React Tutorial (RSCs, Next.js, Sh...
The Modern React Tutorial is FINALLY done. This one took awhile. Shoutout to ALL the awesome sponsors who made this possible: - Vercel - Clerk - Posthog - Sentry - Upstash NOTES I MENTION DURING VIDEO "Nextgram": https://github.com/vercel/nextgram/tree/main/app "useUploadThingInputProps": https://gist.github.com/t3dotgg/0464ca78e94acce80ba04ca...
Vida Zing
Vida ZingOP•3mo ago
If anyone else follows the tutorial, there is a bug in next 14.2 versus the 14.1 this video was made from that prevents redirect('/') from closing your modal dialogs. Took awhile to figure that out 😛
Want results from more Discord servers?
Add your server