Tips for utilizing formidable with NextJS 13 API for image uploading and resolving request errors

I've been working on integrating image uploading functionality into my application. I'm currently using NextJS version 13.4.4 along with formidable@v3. However, whenever I attempt to upload an image, I encounter the following error:

error TypeError: req.on is not a function at IncomingForm.parse (webpack-internal:///(sc_server)/./node_modules/formidable/src/Formidable.js:182:13)

Note: This code functions correctly in previous versions prior to next13.

Below is a snippet of the simple form I am using:

"use client";
import React, { useState } from "react";
import Image from "next/image";
import axios from "axios";

type Props = {};

export default function page({}: Props) {
// Code block for handling file upload and displaying selected image.
}

Additionally, here is the API backend code:

import formidable from "formidable";
import { NextApiRequest } from "next";
import path from "path";
import fs from "node:fs/promises";

// Backend API code snippet implementing file upload logic.

I referenced this code from this source. Could use some guidance on adjusting it for the newer NextJS version.

Answer №1

It's quite simple: the Nextjs App router uses a different request API, making it incompatible with Formidable. To resolve this issue, you can use await req.formData();.

The example below was provided by the Nextjs team and should work properly.

import mime from "mime";
import { join } from "path";
import { stat, mkdir, writeFile } from "fs/promises";
import * as dateFn from "date-fns";
import { NextRequest, NextResponse } from "next/server";

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

  const file = formData.get("file") as Blob | null;
  if (!file) {
    return NextResponse.json(
      { error: "File blob is required." },
      { status: 400 }
    );
  }

  const buffer = Buffer.from(await file.arrayBuffer());
  const relativeUploadDir = `/uploads/${dateFn.format(Date.now(), "dd-MM-Y")}`;
  const uploadDir = join(process.cwd(), "public", relativeUploadDir);

  try {
    await stat(uploadDir);
  } catch (e: any) {
    if (e.code === "ENOENT") {
      await mkdir(uploadDir, { recursive: true });
    } else {
      console.error(
        "Error while trying to create directory when uploading a file\n",
        e
      );
      return NextResponse.json(
        { error: "Something went wrong." },
        { status: 500 }
      );
    }
  }

  try {
    const uniqueSuffix = `${Date.now()}-${Math.round(Math.random() * 1e9)}`;
    const filename = `${file.name.replace(
      /\.[^/.]+$/,
      ""
    )}-${uniqueSuffix}.${mime.getExtension(file.type)}`;
    await writeFile(`${uploadDir}/${filename}`, buffer);
    return NextResponse.json({ fileUrl: `${relativeUploadDir}/${filename}` });
  } catch (e) {
    console.error("Error while trying to upload a file\n", e);
    return NextResponse.json(
      { error: "Something went wrong." },
      { status: 500 }
    );
  }
}

Check out the link for more information:

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using images stored locally in Three.js leads to undefined mapping and attributes

Currently, I am developing a WebGL application using Three.js that involves textures. To enhance my understanding, I have been referring to the tutorials available at . However, when attempting to run the application locally, I encountered several errors. ...

Perform a fetch request within a map function or loop

I'm currently working on iterating over an array of objects. Depending on the content of some of those objects, I need to execute a fetch function and wait for the result before updating the new array. Below is my JavaScript code: const allPosts = ...

Developing several sliders and ensuring they operate independently of each other

I am currently in the process of developing multiple sliders for a website that I am building. As I reach the halfway point, I have encountered a problem that has stumped me. With several sliders involved, I have successfully obtained the length or count ...

In MongoDB, learn the process of efficiently updating nested objects in a dynamic manner

We have a variety of nested configurations stored in MongoDB. Initially, we store the following object in MongoDB: const value = { 'a': { 'b': 1 } } collection.insertOne({userId, value}) Now, I would like to modify the object in ...

Using Ember's transitionTo method and setting a controller attribute within a callback

I am working with Ember code to transition to a specific route while also setting controllerAttr1 on 'my.route' Upon transitioning to "my.route" using this.get('router').transitionTo("my.route"), I have set up a callback function that ...

Utilize the Google Maps API to align an SVG symbol with the direction of an aircraft's

I have been struggling to update the rotation of the Google Maps API SVG aircraft symbol to display the correct heading as it moves. Although it initially loads with the correct heading, I can't seem to figure out how to dynamically update it. I' ...

How to add suspense and implement lazy loading for a modal using Material-UI

Currently, I am implementing <Suspense /> and lazy() to enhance the performance of my project. While everything seems to be working smoothly, I have observed some minor changes in DOM handling that are causing me slight confusion. Consider this scen ...

The connection to the firebase callback

Upon examining this function, it appears that there may be an issue with a null value causing the error message to display: (node:16232) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'groupPages' of null async setTriggers() { ...

Can the .scroll function be turned off when a user clicks on an anchor link that causes the page to scroll?

I am currently developing a timeline page and I want to implement a feature similar to the chronological list of years displayed on the right side of this webpage: As part of this feature, I have set up a click event which adds a circle border around the ...

Separating the rules for development and production modes in the webpack configuration file

I'm currently in the process of working on a front-end project using HTML. Within my project, I have integrated the Webpack module bundler and am utilizing the image-webpack-loader package for image optimization. However, I've encountered an issu ...

Ways to trigger the onclick event from different controls

I have a videojs player and a button on my html page. The videojs player supports the functionality to pause/play the video when clicked. I want to trigger this event by clicking on my button. How can I achieve this? Here is the code that I tried, but it ...

retrieve the source code from all .js links found within the document

There is a file labeled urls.txt. https://website.tld/static/main_01.js https://website.tld/static/main_02.js https://website.tld/static/main_03.js .... All the source code from every .js file in allsource.txt needs to be extracted. Instructions: To ge ...

What is the best method for enabling communication between two users when the identification numbers created by socketIO are automatically generated?

Hey there, hope you're doing well. I've been pondering a question that has left me stumped. I recently came across a course that explained how to send a message to a specific user using socketIO.js by utilizing the `to()` method and passing the ...

Attempting to retrieve dynamically generated input fields and cross-reference them with structured length .json data

In the process of developing code, I've implemented a for loop to dynamically generate HTML input fields based on the length of some data in a .json file. My goal is to use jQuery to compare the text entered in each input field with the corresponding ...

Issues with tabbed navigation functionality in jQuery

I'm encountering some difficulties with the tabbed navigation I created using CSS. Essentially, when a button is clicked, it should remove the hidden class from one div and add it to the other. However, what actually happens is that the div which sho ...

Update the Ngrx reducer when the component is present on the page

One dilemma I am facing involves managing two components within a page - an update user form and a history of events. Each component has its own reducer (user and events). My goal is to update the list of events in the store through an API call once the us ...

Jenkins integration with a MEAN stack application: A step-by-step guide

I'm working on a Mean stack application and looking to integrate Jenkins CI into my workflow. I am uncertain about the steps needed to accomplish this task. Currently, I use bower for installing frontend packages and npm for other functionalities. ...

Emails sent using SendGrid are successful when tested on a local environment, however, they

I'm currently utilizing sendgrid within next.js to handle email communications. Surprisingly, everything functions flawlessly on my local machine. However, upon deployment to Azure app service and attempting to send an email, an error is thrown, with ...

nodemon was not properly installed on the system

I attempted to add nodemon to my application using the command below: npm install nodemon -g This is the output that was generated: changed 116 packages, and audited 117 packages in 8s 16 packages are looking for funding run `npm fund` for details fou ...

Node.js with Koa: Discontinuation of generator usage on the next step

I am working with a custom object in which I pass a parameter, and then I need to search for all documents in my collection and process them. Here is the code for my custom object: var db = require('../lib/db'); function Widget(n,l,c,o,t,p) { ...