How to upload, display and save images in Node.js | GoLinuxCloud

Advertisement

This tutorial shows you how to upload, display and save images in node.js using the express-fileupload, formidable, and multer modules. Apart from the file upload modules, we will use the express server, ejs templating engine, and nodemon to restart the server.

It assumes you want to take a file input on a form, upload it to a Node.js server, and save it before displaying it as a static asset.

Let’s get started.

 

Setup Lab environment

Create the file structure.

fileUploads/
├── expressUpload
│   ├── index.js
│   ├── public
│   │   ├── images
│   │   └── style.css
│   └── views
│       ├── layout.ejs
│       └── upload.ejs
├── formidable
│   ├── index.js
│   ├── public
│   │   ├── images
│   │   └── style.css
│   └── views
│       ├── layout.ejs
│       └── upload.ejs
└── multer
    ├── index.js
    ├── public
    │   ├── images
    │   └── style.css
    └── views
        ├── layout.ejs
        └── upload.ejs

as follows

# main directory
mkdir fileUploads && cd fileUploads
	# subdirectories
mkdir expressUpload formidable multer
		# public
mkdir expressUpload/public formidable/public multer/public
mkdir expressUpload/public/images formidable/public/images multer/public/images
touch expressUpload/public/style.css formidable/public/style.css multer/public/style.css
		# views
mkdir expressUpload/views formidable/views multer/views
touch expressUpload/views/layout.ejs formidable/views/layout.ejs multer/views/layout.ejs
touch expressUpload/views/upload.ejs formidable/views/upload.ejs multer/views/upload.ejs
		# script file
touch expressUpload/index.js formidable/index.js multer/index.js

How to upload, display and save images in Node.js

On Windows, you can run the same commands on Git Bash. Next, include the following code in each subdirectory: expressUpload, formidable, and multer.

public -> images -> style.css

body {
    background-color: #f7f8fc;
}

views -> layout.ejs

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-1BmE4kWBq78iYhFldvKuhfTAU6auU8tT94WrHftjDbrCEXSU1oBoqyl2QvZ6jIW3" crossorigin="anonymous">
    <link rel="stylesheet" href="/style.css">
    <title>Uploads</title>

  </head>
  <body>

    <%- body %>
    
  </body>
</html>

We link Bootstrap 5 for basic styling of the upload.ejs page.

 

views -> upload.ejs

   <div class="container">
        <form class="w-50 mx-auto my-3" action="/uploads" method="post" enctype="multipart/form-data">
            <div class="mb-3">
                <input class="form-control" type="file" name="upload" required>
            </div>
            <button class="btn btn-primary">Upload</button>
        </form>

        <div class="container">
            <div class="row">
                <div class="col my-3">
                    <div class="card" style="width: 18rem;">
                      <img src="/images/image1.jpg" class="card-img-top" alt="Image">
                    </div>
                </div>
                <div class="col my-3">
                    <div class="card" style="width: 18rem;">
                      <img src="/images/image2.jpg" class="card-img-top" alt="Image">
                    </div>
                </div>
                <div class="col my-3">
                    <div class="card" style="width: 18rem;">
                      <img src="/images/image3.jpg" class="card-img-top" alt="Image">
                    </div>
                </div>
            </div>

        </div>
    </div>

NOTE:

Advertisement

Include the upload method post, encoding type multipart/form-data, and file’s name in the form.

Download the (image1, image2, and image3) images. We will be uploading them to the public/images folder of the server.

How to upload, display and save images in Node.js

 

Using the express.static() function implemented in each index.js file, we will let the frontend to fetch images from the server automatically.

Here is how to implement each module in the index.js file.

 

How to upload, display and save images in node.js examples

Example~1: How to upload, display and save images in node.js using the express-upload module

Initialize a package.json file, then install the third-party packages.

cd expressUpload
npm init -y
npm i ejs express express-ejs-layouts express-fileupload
npm i -g nodemon

Update package.json to use nodemon

"start": "nodemon index"

How to upload, display and save images in Node.js

and index.js to upload accept image uploads

const express = require('express')
const ejsLayouts = require('express-ejs-layouts')
const fileUpload = require('express-fileupload')
const path = require('path')
const app = express()
app.use(fileUpload())
app.set('view engine', 'ejs')
app.use(ejsLayouts)
app.use(express.static('public'))
app.use(express.urlencoded({ extended: true }))

//routes
app.get('/', (req, res) => res.render('upload'))
app.post('/uploads', function(req, res) {
    const file = req.files.upload
    const filePath = path.join(__dirname, 'public', 'images', `${file.name}`)
  
    file.mv(filePath, err => {
        if (err) return res.status(500).send(err)
        res.redirect('/')
    })
  })

app.listen(3000)

We grab the incoming (image) file details and store them in the file variable.

const file = req.files.upload

From the file’s name specified in the form input, we create the destination directory and hold it in the filePath variable.

Advertisement

const filePath = path.join(__dirname, 'public', 'images', `${file.name}`)

Using the mv() function (provided by the module), we upload the image to the specified destination.

file.mv(filePath, err => {
	if (err) return res.status(500).send(err)
	res.redirect('/')
})

Lastly, we run the callback function checking if there was an error uploading the image to the server. Otherwise, we redirect the user to the home page.

Start the server.

npm start

Open port 3000 on the browser and try uploading an image.

Before uploading an image

How to upload, display and save images in Node.js

 

After uploading the 3 images

How to upload, display and save images in Node.js

 

Advertisement

Example~2: How to upload, display and save images in node.js using the formidable module

Initialize a package.json then install the third-party packages.

cd ..
cd formidable
npm init -y
npm i ejs express express-ejs-layouts formidable

Update package.json to use nodemon

"start": "nodemon index"

and index.js

const express = require('express')
const ejsLayouts = require('express-ejs-layouts')
const formidable = require('formidable')
const path = require('path')
const fs = require('fs')

const app = express()

app.set('view engine', 'ejs')
app.use(ejsLayouts)
app.use(express.static('public'))
app.use(express.urlencoded({ extended: true }))

//routes

app.get('/', (req, res) => res.render('upload'))
app.post('/uploads', (req, res) => {
  const form = new formidable.IncomingForm()
  const filePath = path.join(__dirname, 'public', 'images')
  form.uploadDir = filePath
  form.parse(req, async (err, fields, files) => {
    if (err) res.send("Error parsing the files")
    const file = files.upload
    const fileName = file.originalFilename
    fs.renameSync(file.filepath, path.join(filePath, fileName))
    res.redirect("/")
  })
})

app.listen(4000)

We create an instance of the form data (from the client-side) and store the result in the form variable.

const form = new formidable.IncomingForm()

Using the object’s uploadDir attribute, we tell the module to store the uploaded file in the public directory’s images directory referenced by the filePath variable. Using other attributes like multiples and maxFileSize, we could control file size and whether we need multiple uploads.
Next, we parse the files in the object’s parse() method, which takes the request object and a callback function returning error, fields, and files objects.

form.parse(req, async (err, fields, files) => {} )

We then store the filename in a format we want (.jpg) by renaming the initially saved file.

const file = files.upload
const fileName = file.originalFilename
fs.renameSync(file.filepath, path.join(filePath, fileName))

Lastly, we redirect the user to the home page.

res.redirect("/")

Start the server.

npm start

Open port 4000 on the browser and upload the three images.

How to upload, display and save images in Node.js

Example~3: How to upload, display and save images in node.js using the multer module

Initialize a package.json then install the third-party packages.

Advertisement

cd ..
cd multer
npm init -y
npm i ejs express express-ejs-layouts multer

Update package.json to accommodate nodemon

"start": "nodemon index"

and index.js

// import modules
const express = require('express')
const ejsLayouts = require('express-ejs-layouts')
const multer = require('multer')
const path = require('path')

// create server
const app = express()

// configure templating engine
app.set('view engine', 'ejs')
app.use(ejsLayouts)

// make public directory's files static
app.use(express.static('public'))

// handle form data
app.use(express.urlencoded({ extended: true }))

// Configure multer
const storageEngine = multer.diskStorage({
  destination: (req, file, callback) => {
    callback(null, path.join(__dirname, 'public', 'images'))
  },
  filename: (req, file, callback) => {
    callback(null, file.originalname)
  }
})

const upload = multer({ storage: storageEngine })

// routes
app.get('/', (req, res) => res.render('upload'))

app.post('/uploads', upload.single('upload'), async (req, res) => {
  res.redirect("/")
})

app.listen(5000)

The diskStorage() function allows us to store files on the disk. We pass it to two objects, each accepting the request object, file, and a callback function. The callback checks for any error (null) before handling file saving as follows:

destination: We tell the module to save images in the images directory inside the public directory.filename: We tell multer to save the image’s original name in the specified destination.

We then ship the packed destination and filename to multer and run the middleware before hitting the /uploads endpoint.

How to upload, display and save images in node.js

Start the server.

npm start

Open port 5000 on the browser and upload the images.

How to upload, display and save images in Node.js

 

Conclusion

Knowing how to upload, display and save images in node.js is a key step toward handling images in a Node.js server. After uploading the images, you can save them on the server, upload them to a CDN or save them in a database.

This tutorial walked you through one of the most challenging parts: uploading images to a Node.js server. You saw how to upload images with the express-fileupload, formidable and multer modules. Next, you saved the images in a public directory and displayed them on the landing page.

You can find the complete code on GitHub.