Hi, I encounter a strange bug when doing client upload on preview env (it works as expected locally with ngrok and I did not try it in production as huh… test in production is never a good idea).
The problem is related to the random hidden use of window object inside the upload api route.
Random because I use the upload function client side to upload a lot of files, sometimes the api route handle the request normally and all works as expected, sometimes not without any difference in upload() parameters client side.
Here is a simple implementation :
import { getServerSession } from "next-auth";
import { NextRequest, NextResponse } from "next/server";
import { authOptions } from "../../auth/[...nextauth]/route";
import { handleUpload, type HandleUploadBody } from "@vercel/blob/client";
export async function POST(request: NextRequest) {
const body = (await request.json()) as HandleUploadBody;
try {
const jsonResponse = await handleUpload({
body,
request,
onBeforeGenerateToken: async (
pathname: string
/* clientPayload?: string, */
) => {
const session = await getServerSession(authOptions);
if (!session?.organization?.id) {
throw new Error("Not authorized");
}
if (typeof window !== "undefined") {
console.log("Window is defined unexpectedly!");
// @ts-ignore
window = undefined;
} else {
console.log("window is not defined");
}
return {
allowedContentTypes: ["image/jpeg", "image/png", "image/avif", "image/webp"],
tokenPayload: JSON.stringify({
organizationId: session.organization.id,
}),
};
},
onUploadCompleted: async ({ blob, tokenPayload }) => {
console.log("blob upload completed", blob.pathname, tokenPayload);
},
});
return NextResponse.json(jsonResponse);
} catch (error) {
console.log("error", error);
console.log("error saving images", body);
return NextResponse.json(
{ error: (error as Error).message },
{ status: 400 } // The webhook will retry 5 times waiting for a 200
);
}
}
and here is the client side implementation :
const res = await upload(fileName, imageFile.rawFile, {
access: "public",
handleUploadUrl: uploadUrl + "/api/images/upload",
});
Without setting windows to undefined if it is defined I got the following error :
“Vercel Blob: "generateClientTokenFromReadWriteToken" must be called from a server environment”
After checking the @vercel/blob code, i found a check on window in generateClientTokenFromReadWriteToken() function.
So, even if I do not know why window is randomly defined hence I don’t think to use any library on server side which create the window variable, I tried to set it to undefined. But after that I got the error :
“window is not defined”
How this error could be thrown ?
Is any of you have been confronted to this issue ?
Do you have any clue ?
I use the latest @vercel/blob realease.