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!