From 8b10c68e17d9e4cf409a53627852a473545d627d Mon Sep 17 00:00:00 2001 From: ledgerpilot Date: Wed, 8 Apr 2026 00:08:37 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20address=20issue=20#561=20=E2=80=94=20nex?= =?UTF-8?q?t-image=20template:=20Request=20Entity=20Too=20Large?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/app/api/upload-image/route.ts | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 templates/next-image/src/app/api/upload-image/route.ts diff --git a/templates/next-image/src/app/api/upload-image/route.ts b/templates/next-image/src/app/api/upload-image/route.ts new file mode 100644 index 000000000..68e4b306d --- /dev/null +++ b/templates/next-image/src/app/api/upload-image/route.ts @@ -0,0 +1,55 @@ +import { type NextRequest, NextResponse } from 'next/server'; +import { put } from '@vercel/blob'; + +// IMPORTANT: For local development, ensure you have a .env.local file with: +// BLOB_READ_WRITE_TOKEN="YOUR_VERCEL_BLOB_READ_WRITE_TOKEN" +// You can generate a token in your Vercel project settings under 'Storage' -> 'Blob' -> 'API Keys'. + +export const config = { + // This API route explicitly handles multipart/form-data for file uploads, + // so we disable Next.js's default body parser to process the file stream manually. + api: { + bodyParser: false, + }, +}; + +export async function POST(request: NextRequest): Promise { + if (!process.env.BLOB_READ_WRITE_TOKEN) { + return NextResponse.json( + { error: 'Vercel Blob storage token not configured. Please set BLOB_READ_WRITE_TOKEN environment variable.' }, + { status: 500 } + ); + } + + const formData = await request.formData(); + const file = formData.get('file') as File | null; + + if (!file) { + return NextResponse.json({ error: 'No file uploaded.' }, { status: 400 }); + } + + if (file.size === 0) { + return NextResponse.json({ error: 'Uploaded file is empty.' }, { status: 400 }); + } + + try { + // Sanitize filename to prevent issues, especially with special characters or path traversals. + // Appending a timestamp or UUID is also common to ensure uniqueness. + const filename = `${Date.now()}-${encodeURIComponent(file.name.replace(/[^a-zA-Z0-9.\-_]/g, '_'))}`; + + // Upload the file to Vercel Blob storage + const blob = await put(filename, file, { + access: 'public', // Make the uploaded image publicly accessible via URL + token: process.env.BLOB_READ_WRITE_TOKEN, + }); + + // Return the URL of the uploaded blob + return NextResponse.json({ url: blob.url }); + } catch (error) { + console.error('Error uploading file to Vercel Blob:', error); + return NextResponse.json( + { error: 'Failed to upload image. Please try again.' }, + { status: 500 } + ); + } +}