Uploading images is a common feature in modern web applications, whether for user profiles, e-commerce, or blog posts. In this guide, you'll learn how to integrate Cloudinary, a powerful asset management tool, into your Express.js application. We'll use Multer for seamless file handling, making it a breeze to upload and store images.
Cloudinary offers:
Before we begin, make sure you have:
First, let's create a new Express project and install the required dependencies:
mkdir express-cloudinary-upload cd express-cloudinary-upload npm init -y npm install express multer cloudinary dotenv
Create a .env file in your project root to store your Cloudinary credentials:
env
CLOUDINARY_CLOUD_NAME=your_cloud_name CLOUDINARY_API_KEY=your_api_key CLOUDINARY_API_SECRET=your_api_secret
create a util folder within the util folder create a cloudinary.ts file.
import { v2 as cloudinary } from 'cloudinary'
import dotenv from 'dotenv';
dotenv.config();
cloudinary.config({
cloud_name: process.env.CLOUD_NAME,
api_key: process.env.API_KEY,
api_secret: process.env.API_SECRET,
secure: true
});
export default cloudinary;create a multer.ts file within the util folder
import multer, { FileFilterCallback } from "multer";
import { Request } from 'express';
import { Readable } from 'stream';
import cloudinary from "./cloudinary";
const acceptedMimeTypes = ['image/jpeg', 'image/jpg', 'image/png', 'image/gif', 'image/JPG'];
// Validate file
const checkFile = (file: Express.Multer.File, cb: FileFilterCallback): void => {
if (!acceptedMimeTypes.includes(file.mimetype)) {
cb(new Error('Invalid file type'));
return;
}
cb(null, true);
};
// Use memory storage
const storage = multer.memoryStorage();
const upload = multer({
storage: storage,
fileFilter: function(req: Request, file: Express.Multer.File, cb: FileFilterCallback) {
checkFile(file, cb);
},
limits: { fileSize: 524288000 }, // ~500MB
});
// Function to upload buffer to Cloudinary
const uploadToCloudinary = (file: Express.Multer.File): Promise<{ publicId: string; imageUrl: string }> => {
return new Promise((resolve, reject) => {
const uploadStream = cloudinary.uploader.upload_stream(
{ resource_type: 'auto' },
(error, result) => {
if (error) return reject(error);
resolve({
publicId: result!.public_id,
imageUrl: result!.secure_url
});
}
);
const readableStream = new Readable();
readableStream.push(file.buffer);
readableStream.push(null);
readableStream.pipe(uploadStream);
});
};
export default { upload, uploadToCloudinary };It uses memory storage to upload to cloudinary which improves upload performance.
Inside your route you make use of multer this way. An example is shown below
router.route("/change-pic/:id").post(authMiddleware.verifyToken, multer.upload.single("image"), customer.changePassportPic)
At DevelopersMonk, we share tutorials, tips, and insights on modern programming frameworks like React, Next.js, Spring Boot, and more. Join us on our journey to simplify coding and empower developers worldwide!