Skip to content

Instantly share code, notes, and snippets.

@konojunya
Created February 12, 2021 03:06
Show Gist options
  • Save konojunya/b337a4e048b5dac4f9385b5a0cfd7c62 to your computer and use it in GitHub Desktop.
Save konojunya/b337a4e048b5dac4f9385b5a0cfd7c62 to your computer and use it in GitHub Desktop.
Next.js file uploader with busboy
import { NextApiRequest, NextApiResponse } from 'next';
import Busboy from 'busboy';
import { inspect } from 'util';
export const config = {
api: {
bodyParser: false,
},
};
async function r(req: NextApiRequest) {
return new Promise((resolve) => {
const busboy = new Busboy({ headers: req.headers });
console.log(JSON.stringify(req.headers, null, 2));
busboy.on('file', function (fieldname, file, filename, encoding, mimetype) {
console.log(
'File [' + fieldname + ']: filename: ' + filename + ', encoding: ' + encoding + ', mimetype: ' + mimetype,
);
file.on('data', function (data) {
console.log('File [' + fieldname + '] got ' + data.length + ' bytes');
});
file.on('end', function () {
console.log('File [' + fieldname + '] Finished');
});
});
busboy.on('field', function (fieldname, val) {
console.log('Field [' + fieldname + ']: value: ' + inspect(val));
});
busboy.on('finish', function () {
console.log('Done parsing form!');
resolve(1);
});
req.pipe(busboy);
});
}
export default async function imageUploadHandler(req: NextApiRequest, res: NextApiResponse) {
if (req.method !== 'POST') {
return res.status(405).end();
}
await r(req);
res.status(200).end(JSON.stringify({ ok: true }));
}
@dlamprey
Copy link

Thanks so much for sharing this! I wish I found it a day ago as I struggled to figure out how to make this work as the code examples for busboy, multiparty, and formidable packages don't wrap the streaming functions in a promise. 👍

@vatoer
Copy link

vatoer commented May 12, 2023

hey, can you update it with nextjs 13,
I'm trying to implement this code on nextjs 13 with /app/api/image/routes.ts
thanks

@gurvirbaraich
Copy link

@vatoer Here is the implementation to upload files in NextJS 13.

async function upload(request: NextRequest) {
  const formData = await request.formData();

  return new Promise(function (resolve, reject) {
    // @ts-ignore
    const videos: File | null = formData.get("videos");

    if (!videos) {
      resolve(false);
    }

    const timestamp = Date.now();
    const filename = path.join(process.cwd(), `uploads/${timestamp}.mp4`);

    const fileStream = createWriteStream(filename);

    const videoReadableStream = new Readable(); // Create a new Readable stream
    videoReadableStream._read = () => {}; // Implement the _read function to satisfy stream requirements

    videos?.arrayBuffer().then((buffer) => {
      videoReadableStream.push(Buffer.from(buffer)); // Push the video data to the readable stream
      videoReadableStream.push(null); // Signal the end of the data

      videoReadableStream
        .pipe(fileStream)
        .on("error", (error) => {
          console.error("Error while saving the file:", error);
          resolve(false);
        })
        .on("finish", () => {
          console.log("File saved successfully");
          resolve(true);
        });
    });
  });
}

@gurvirbaraich
Copy link

export const POST = async function (request: NextRequest) {
  const status = await upload(request);

  return NextResponse.json({
    status,
  });
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment