How to Upload Single/Multiple Image to Cloudinary using Node.js ?
Last Updated :
31 Jul, 2024
Uploading images to Cloudinary from a Node.js application is a common task when you need to manage and store images in the cloud. Cloudinary is a cloud-based service that provides comprehensive solutions for image and video management, including upload, storage, manipulation, and delivery.
Approach
to upload single/multiple image to Cloudinary using node.js we will use the Cloudinary npm package to configure with your credentials. Upload single images with cloudinary.uploader.upload('path')
, and multiple images using Promise.all(images.map(path => cloudinary.uploader.upload(path)))
.
Installation Steps
Step 1: Make a folder structure for the project.
mkdir myapp
Step 2:Â Navigate to the project directory
cd myapp
Step 3: Initialize the NodeJs project inside the myapp folder.
npm init -y
Step 4: Install the required npm packages using the following command.
npm install express multer cloudinary
Project Structure:
The updated dependencies in package.json file will look like:
"dependencies": {
"cloudinary": "^2.2.0",
"express": "^4.19.2",
"multer": "^1.4.5-lts.1"
}
Example: Implementation to show how to upload single/multiple image to cloudinary .
HTML
<!-- index.html -->
<html>
<head>
<title>Upload Single/Multiple Image to Cloudinary using Node.js</title>
</head>
<body style="padding: 30px;">
<form method="POST"
action="/profile-upload-single"
enctype="multipart/form-data">
<div>
<label>Upload profile picture</label>
<input type="file" name="profile-file" required />
</div>
<div>
<input type="submit" value="Upload" />
</div>
</form>
<br>
<hr><br>
<form method="POST"
action="/profile-upload-multiple"
enctype="multipart/form-data">
<div>
<label>Upload multiple profile picture</label>
<input type="file"
name="profile-files" required multiple />
</div>
<div>
<input type="submit" value="Upload" />
</div>
</form>
</body>
</html>
JavaScript
// index.js
// Requiring module
const express = require("express");
const multer = require("multer");
const port = 3000;
const app = express();
const cloudinary = require("cloudinary").v2;
const bodyParser = require("body-parser");
const fs = require("fs");
// Creating uploads folder if not already present
// In "uploads" folder we will temporarily upload
// image before uploading to cloudinary
if (!fs.existsSync("./uploads")) {
fs.mkdirSync("./uploads");
}
// Multer setup
let storage = multer.diskStorage({
destination: function (req, file, cb) {
cb(null, "./uploads");
},
filename: function (req, file, cb) {
cb(null, file.originalname);
},
});
let upload = multer({ storage: storage });
// Body parser configuration
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(express.static(__dirname + "/public"));
app.use("/uploads", express.static("uploads"));
// Cloudinary configuration
cloudinary.config({
cloud_name: "YOUR_CLOUD_NAME",
api_key: "YOUR_API_NAME",
api_secret: "YOUR_API_SECRET",
});
async function uploadToCloudinary(locaFilePath) {
// locaFilePath: path of image which was just
// uploaded to "uploads" folder
let mainFolderName = "main";
// filePathOnCloudinary: path of image we want
// to set when it is uploaded to cloudinary
let filePathOnCloudinary =
mainFolderName + "/" + locaFilePath;
return cloudinary.uploader
.upload(locaFilePath, { public_id: filePathOnCloudinary })
.then((result) => {
// Image has been successfully uploaded on
// cloudinary So we dont need local image
// file anymore
// Remove file from local uploads folder
fs.unlinkSync(locaFilePath);
return {
message: "Success",
url: result.url,
};
})
.catch((error) => {
// Remove file from local uploads folder
fs.unlinkSync(locaFilePath);
return { message: "Fail" };
});
}
function buildSuccessMsg(urlList) {
// Building success msg to display on screen
let response = `<h1>
<a href="/">Click to go to Home page</a><br>
</h1><hr>`;
// Iterating over urls of images and creating basic
// html to render images on screen
for (let i = 0; i < urlList.length; i++) {
response += "File uploaded successfully.<br><br>";
response += `FILE URL: <a href="${urlList[i]}">
${urlList[i]}</a>.<br><br>`;
response += `<img src="${urlList[i]}" /><br><hr>`;
}
response += `<br>
<p>Now you can store this url in database or
// do anything with it based on use case.</p>
`;
return response;
}
app.post(
"/profile-upload-single",
upload.single("profile-file"),
async (req, res, next) => {
// req.file is the `profile-file` file
// req.body will hold the text fields,
// if there were any
// req.file.path will have path of image
// stored in uploads folder
let locaFilePath = req.file.path;
// Upload the local image to Cloudinary
// and get image url as response
let result = await uploadToCloudinary(locaFilePath);
// Generate html to display images on web page.
let response = buildSuccessMsg([result.url]);
return res.send(response);
}
);
app.post(
"/profile-upload-multiple",
upload.array("profile-files", 12),
async (req, res, next) => {
// req.files is array of `profile-files` files
// req.body will contain the text fields,
// if there were any
let imageUrlList = [];
for (let i = 0; i < req.files.length; i++) {
let locaFilePath = req.files[i].path;
// Upload the local image to Cloudinary
// and get image url as response
let result = await uploadToCloudinary(locaFilePath);
imageUrlList.push(result.url);
}
let response = buildSuccessMsg(imageUrlList);
return res.send(response);
}
);
app.listen(port, () => {
console.log(`Server running on port ${port}!
\nClick http://localhost:3000/`);
});
Step to Run Application:Â Run the application using the following command from the root directory of the project
node index.js
Output: Open the browser and visit http://localhost:3000. You could now see the following 2 forms i.e single and multiple image upload as shown below.
Additional Considerations
- Security: Use environment variables to manage sensitive API credentials.
- Validation: Implement file size limits and format validations to avoid unnecessary uploads.
- Error Handling: Add comprehensive error handling to manage upload failures and Cloudinary errors.
Conclusion
Uploading images to Cloudinary using Node.js is straightforward and efficient with the help of the cloudinary
and multer
packages. This guide covers both single and multiple image uploads, providing a solid foundation for managing images in your Node.js applications.
References: https://cloudinary.com/documentation/node_integration.