How to Upload Images in Node.js Using Multer

There are three main ways of handling file uploads in Node.js: saving the images directly to your server, saving the image’s binary data or base64 string data to your database, and using Amazon Web Service (AWS) S3 buckets to save and manage your images.

Here you will learn how to use Multer, a Node.js middleware, to upload and save images directly to your server in Node.js applications in a few steps.

Step 1: Setting Up Development Environment

The code used in this project is available in a GitHub repository and is free for you to use under the MIT license.

First, create a project folder and move into it by running the following command:

 mkdir multer-tutorial

cd

multer-tutorial

Next, initialize npm in your project directory by running:

 npm init -y

Next, you will need to install some dependencies. The dependencies required for this tutorial include:

  • Express: Express is a Node.js framework that provides a robust set of features for web and mobile applications. It makes it easier to build backend applications with Node.js.
  • Multer: Multer is an express middleware that simplifies uploading and saving images to your server.

Install the packages with the node package manager by running:

 npm 

install

express multer

Next, create an app.js file in your project’s root directory and add the code block below to create a basic Express server:

 

const

express =

require

(

'express'

);

const

app = express();

const

port = process.env.PORT ||

3000

;

app.listen(port, ()=>{
    

console

.log(

`App is listening on port

${port}

`);
});

Step 2: Configuring Multer

First, import multer in your app.js file.

 

const

multer =

require

(

"multer"

);

multer requires a storage engine that contains information about the directory where the uploaded files will be stored and how the files will be named.

A multer storage engine is created by calling the diskStorage method on the imported multer module. This method returns a StorageEngine implementation configured to store files on the local file system.

It takes a configuration object with two properties: destination, which is a string or function that specifies where the uploaded images will be stored.

The second property, filename, is a function that determines the uploaded files’ names. It takes three parameters: req, file, and a callback (cb). req is the Express Request object, file is an object containing information about the processed file, and cb is a callback that determines the uploaded files’ names. The callback function takes error and filename as arguments.

Add the code block below to your app.js file to create a storage engine:

 

const

storageEngine = multer.diskStorage({
  destination:

"./images"

,
  filename:

(

req, file, cb

) => {
    cb(

null

,

`

${

Date

.now()}--

${file.originalname}

`);
  },
});

In the code block above, you set the destination property to ”./images”, thus, the images will be stored in your project’s directory in an images folder. Then, in the callback, you passed null as the error and a template string as the file name. The template string consists of a timestamp generated by calling Date.now() to ensure that the image names are always unique, two hyphens to separate the filename and the timestamp, and the file’s original name, which can be accessed from the file object.

The resulting strings from this template will look like this: 1663080276614–example.jpg.

Next, you need to initialize multer with the storage engine.

Add the code block below to your app.js file to initialize multer with the storage engine:

 

const

upload = multer({
  storage: storageEngine,
});

multer returns a Multer instance that provides several methods for generating middleware that processes files uploaded in multipart/form-data format.

In the code block above, you pass a configuration object with a storage property set to storageEngine, which is the storage engine you created earlier.

Currently, your Multer configuration is complete, but there are no validation rules that ensure that only images can be saved on your server.

Step 3: Adding Image Validation Rules

The first validation rule you can add is the maximum size allowed for an image to be uploaded to your application.

Update your multer configuration object with the below code block:

 

const

upload = multer({
  storage: storageEngine,
  

limits

: {

fileSize

:

1000000

},
});

In the code block above, you added a limits property to the configuration object. This property is an object that specifies various limits on incoming data. You set the fileSize property, with which the max file size in bytes is set to 1000000, which is equivalent to 1MB.

Another validation rule you can add is the fileFilter property, an optional function to control which files are uploaded. This function is called for every file that is processed. This function takes the same parameters as the filename function: req, file, and cb.

To make your code cleaner and more reusable, you’ll abstract all the filtering logic into a function.

Add the code block below to your app.js file to implement the file filtering logic:

 

const

path =

require

(

"path"

);

const

checkFileType =

function

(

file, cb

) {
  
  

const

fileTypes =

/jpeg|jpg|png|gif|svg/

;

  //

check

extension

names


  

const

extName = fileTypes.test(path.extname(file.originalname).toLowerCase());

  

const

mimeType = fileTypes.test(file.mimetype);

  if (mimeType && extName) {
    

return

cb(

null

,

true

);
  }

else

{
    cb(

"Error: You can Only Upload Images!!"

);
  }
};

The checkFileType function takes two parameters: file and cb.

In the code block above, you defined a fileTypes variable that stores a regex expression with the allowed image file extensions. Next, you called the test method on the regex expression.

The test method checks for a match in the passed string and returns true or false depending on whether it finds a match. Then, you pass the uploaded file name, which you can access through file.originalname, into the path’s module extname method, which returns the extension of the string path to it. Finally, you chain the JavaScript toLowerCase string function to the expression to handle images with their extension names in uppercase.

Checking the extension name alone is not enough, as extension names can be easily edited. To ensure that only images are uploaded, you have to check the MIME type too. You can access a file’s mimetype property through the file.mimetype. So, you check for the mimetype property using the test method as you did for the extension names.

If the two conditions return true, you return the callback with null and true, or you return the callback with an error.

Finally, you add the fileFilter property to your multer configuration.

 

const

upload = multer({
  storage: storageEngine,
  

limits

: {

fileSize

:

10000000

},
  fileFilter:

(

req, file, cb

) => {
    checkFileType(file, cb);
  },
});

Step 4: Using Multer as an Express Middleware

Next, you have to implement route handlers that’ll handle the image uploads.

Multer can handle both single and multiple image uploads depending on the configuration.

Add the code block below to your app.js file to create a route handler for single image uploads:

 app.post(

"/single"

, upload.single(

"image"

), (req, res) => {
  

if

(

req

.file

) {
    res.send(

"Single file uploaded successfully"

);
  }

else

{
    

res

.status

(400)

.send

("

Please

upload

a

valid

image

");
  }
});

In the code block above, you called the single method on the upload variable, which stores your multer configuration. This method returns a middleware that processes a “single file” associated with the given form field. Then, you passed the image as the form field.

Finally, check if a file was uploaded through the req object in the file property. If it was, you send a success message, else you send an error message.

Add the code block below to your app.js file to create a route handler for multiple image uploads:

 app.post(

"/multiple"

, upload.

array

(

"images"

,

5

), (req, res) => {
  

if

(

req

.files

) {
    res.send(

"Muliple files uploaded successfully"

);
  }

else

{
    

res

.status

(400)

.send

("

Please

upload

a

valid

images

");
  }
});

In the code block above, you called the array method on the upload variable, which stores your multer configuration. This method takes two arguments—a field name and a max count—and returns middleware that processes multiple files sharing the same field name. Then, you passed images as the shared form field and 5 as the maximum number of images that can be uploaded at once.

Advantages of Using Multer

Using Multer in your Node.js applications simplifies the otherwise complicated process of uploading and saving images directly on your server. Multer is also based on busboy, a Node.js module for parsing incoming form data, making it very efficient for parsing form data.