This post help you figure out how to post a binary file (image/file) via api route using formidable.
Making Next.js just pass the file from front-end as it is to the back-end does not work!
You need to do modify the file in the api route before sending to the back.
Next.js: 13.0.6
Node.js: 16.17.1
pages/upload.tsx
This is the brief overview of the front-end code.
const response = await axios.post(
'/api/upload',
{
file,
title: 'sample title'
},
{
headers: {
'content-type': 'multipart/form-data',
},
}
);
pages/api/upload.tsx
First, you need to disable body parsing in Next.js by this.
https://nextjs.org/docs/api-routes/request-helpers
export const config = {
api: {
bodyParser: false,
},
};
Then, parse the file data using formidable.
The parsed data is passed to the api call as a parameter: file
has file object, whilefields
has non-file request parameters.
The file object is conveted to a readable stream by fs.createReadStream()
.
import { IncomingForm } from 'formidable';
import fs from 'fs';
import { NextApiRequest, NextApiResponse } from 'next';
export const config = {
api: {
bodyParser: false,
},
};
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
const form = new IncomingForm();
form.parse(req, async (err, fields, files: any) => {
try {
const { data } = await axios.post(
`${END_POINT_OF_BACKEND}`,
{ ...fields, file: fs.createReadStream(files.file.filepath) },
{
headers: {
'content-type': req.headers['content-type'],
},
}
);
res.send(data);
} catch (e: any) {
res.status(e.status ?? 500).json(e);
}
});
};
export default handler;