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

What are the steps to ensure compatibility with relative paths when transitioning from v5 to v6?

In my application, there are scenarios where multiple routes must pass through a component before rendering specifics. Additionally, there are situations where something is displayed for the parent route and then divided for the children. It's crucia ...

Is there a term in JavaScript that denotes an object that can be serialized into JSON format?

Can you help me find a term for basic objects that accentuates their simplicity? Particularly, objects that do not reference themselves and do not have any methods or bindings (i.e. JSON-serializable). The terms I am currently using are: "flat object" " ...

Tips for eliminating unnecessary or duplicate dependencies in package.json files

While I am aware that this question has been asked previously on Stack Overflow, I have found that depcheck does not work effectively for me. It provides numerous false alerts and requires specific configuration for libraries like babel, eslint, etc. How ...

Enhance user experience with dynamic color changes in JavaScript

Looking to create a navigation menu with unique colors for each selected state? Check out the code below! After searching extensively, I stumbled upon this snippet. While it only includes one selected state, you can easily customize it for three different ...

Tips for modifying the value of a JSON object using Javascript or Jquery

I am looking to retrieve the value of a specific key, potentially accessing nested values as well. For example, changing the value of "key1" to "value100" or "key11" to "value111. { "key1": "value1", "key2": "value2", ...

What steps can I take to resolve the issue in my code? I keep receiving a type error stating that it cannot read

I seem to be encountering an issue when running my code where I receive a 'cannot read property 'age' of null'. This error breaks my code, and I'm trying to figure out how to implement a check to ensure it only runs when I am signe ...

Modify the text on a button using vanilla JavaScript

Although it may seem like a simple question, I am struggling to change the text on my button. The code for my button in the web browser console is: <button class="nav-link active" id="coholder-tab" data-toggle="tab" data-t ...

Identifying the moment when the body scroll reaches the top or bottom of an element

I have been experimenting with javascript and jquery to determine when the window scroll reaches the top of a specific element. Although I have been trying different methods, I have yet to see any successful outcomes: fiddle: https://jsfiddle.net/jzhang17 ...

Utilizing Vue to create a button within a popup window

Utilizing the vue2-google-maps package, I have created a custom popup. Within this custom popup, there is a button that is intended to open a new popup in place of the existing one. Here is the HTML code: <gmap-info-window :options="infoOptions" : ...

What could be causing the 404 error I'm receiving for this specific URL?

Can someone explain why I keep encountering a 404 error when I type \book into the URL bar? Below is the code I am currently using: var express = require('express'), app = express(), chalk = require('chalk'), debug = ...

What is the best way to leverage the SWR hook for implementing all CRUD operations with API methods?

I am updating my CRUD functionality to use SWR instead of tokens. I have successfully implemented this hook for GET methods, but I'm struggling with the others. Any guidance on how to handle this? export default function useGetData(apiKey) { const fet ...

Can JavaScript be used to modify the headers of an HTTP request?

Can JavaScript be used to modify or establish HTTP request headers? ...

Is there a way to incorporate jQuery into SharePoint 2010?

I am encountering an issue with linking my HTML page to our organization's SharePoint 2010 portal. All necessary files (CSS, images, jQuery) are stored in the same document library. While the CSS is functioning properly, I am facing challenges with ge ...

Using onchange within an onchange event will not function as intended

When I am in the process of creating 2 dropdown menus filled from a database, the issue arises when the second dropdown is generated after selecting a value from the first one. Upon choosing an option from the second dropdown, my ajax function is triggered ...

Angular 4 - The Promising Outcome: How to Retrieve the Value upon Completion

Is there a way to retrieve a value from a promise and store it in a global variable? I've been attempting to accomplish this, but the global variable remains undefined. import { Injectable } from '@angular/core'; import {ActivatedRouteSnap ...

Using regular expressions to identify the presence of "&", parentheses, and consecutive letters in a string

I specialize in working with JavaScript and I have a need to verify if my text contains certain characters. Specifically, I want to check for the presence of parentheses (), ampersands (&), and repeating letters within the text. Here are some examples: te ...

Javascript use of overlaying dynamically generated Canvases

Currently, I am developing a game to enhance my skills in HTML5 and Javascript. In the beginning, I had static canvases in the HTML body but found it difficult to manage passing them around to different objects. It is much easier for me now to allow each ...

Is it possible to create dynamic meta tags in Angular that will appear in a Twitter-style card preview?

My project involves building a dynamic website using a Java app that serves up a REST-ish JSON API along with an Angular9 front end. A key requirement is the ability to share specific URLs from the app on platforms like Twitter and Slack, which support Twi ...

Create a generic function that retrieves a specific property from an array of objects using the select method

Currently, I have implemented four functions that select entries from an array based on different properties. if ($scope.filters.filter1) $scope.filteredEntries = $scope.filteredEntries.filter(function (o) { return o.field1 === $scope.filt ...

Minimize unnecessary rendering in React when toggling between tabs

I am currently working on a React application that utilizes material-ui to generate tabs. <div className={classes.root}> <AppBar position="static"> <Tabs value={value} onChange={handleChange}> <Tab label="Item One" /> ...