shawn
shawn
TTCTheo's Typesafe Cult
Created by shawn on 3/26/2025 in #questions
Auth in middleware
Obviously there has been a lot of recent discussion about authentication in next middleware. I’ve gathered that the general sentiment is that it is best to confirm auth closer to the data. I’m working on my first next app now, so that is the practice I’m following. But as im integrating uploadthing into my project, I see them recommending auth checks in the uploadthing middleware in the docs. So I’m a bit confused on when it is and isn’t ok to check auth in your middleware. Is it always just as an optimistic check?
20 replies
TTCTheo's Typesafe Cult
Created by shawn on 3/25/2025 in #questions
Files uploaded, but client and server never reach onUploadComplete
My files are uploading successfully to UploadThing (I can access them in dashboard), but the loading spinner goes indefinitely on client. onUploadComplete is not being triggered on server or client, and onUploadError is not being triggered clientside either. I had everything working fine the other day on setup, not sure what I did to fuck up. No errors in log on client or server. Any help is appreciated, thanks! next: 15.2.3 uploadthing: 7.6.0 component.tsx
<UploadButton
endpoint="inputSource"
onClientUploadComplete={() => {
refetch();
}}
onUploadError={(error: Error) => {
console.log('upload error', error);
}}
className="my-4"
/>
<UploadButton
endpoint="inputSource"
onClientUploadComplete={() => {
refetch();
}}
onUploadError={(error: Error) => {
console.log('upload error', error);
}}
className="my-4"
/>
route.ts
import { createRouteHandler } from 'uploadthing/next';
import { uploadRouter } from './core';

export const { GET, POST } = createRouteHandler({
router: uploadRouter,
});
import { createRouteHandler } from 'uploadthing/next';
import { uploadRouter } from './core';

export const { GET, POST } = createRouteHandler({
router: uploadRouter,
});
core.ts
export const uploadRouter = {
inputSource: f({
image: {
maxFileSize: '8MB',
maxFileCount: 1,
},
})
.middleware(async () => {
const { userId } = await auth();
if (!userId) throw new UploadThingError('Unauthorized');
return { userId };
})
.onUploadComplete(async ({ file }) => {
const caller = appRouter.createCaller(await createTRPCContext());
const { error } = await tryCatch(
caller.input.createInputSource({
url: file.ufsUrl,
type: 'IMAGE',
}),
);
if (error) throw new UploadThingError(error.message);
}),
} satisfies FileRouter;
export const uploadRouter = {
inputSource: f({
image: {
maxFileSize: '8MB',
maxFileCount: 1,
},
})
.middleware(async () => {
const { userId } = await auth();
if (!userId) throw new UploadThingError('Unauthorized');
return { userId };
})
.onUploadComplete(async ({ file }) => {
const caller = appRouter.createCaller(await createTRPCContext());
const { error } = await tryCatch(
caller.input.createInputSource({
url: file.ufsUrl,
type: 'IMAGE',
}),
);
if (error) throw new UploadThingError(error.message);
}),
} satisfies FileRouter;
2 replies