DEV Community

Prathviraj H
Prathviraj H

Posted on

**Optimizing Image Management in CampusX with Cloudinary**

Why Cloudinary?

Cloudinary is a powerful cloud-based image and video management service that enables developers to store, optimize, and deliver media files efficiently. By leveraging Cloudinary, CampusX significantly reduces the load time of images, ensuring a seamless user experience. Instead of storing images on local servers, which can slow down performance and consume storage, Cloudinary serves optimized images via a CDN, reducing latency and bandwidth consumption.

Key Benefits of Using Cloudinary in CampusX

  1. Efficient Storage & Delivery: Images are stored in Cloudinary’s cloud storage and served via their CDN, improving load times.
  2. On-the-Fly Optimization: Cloudinary automatically compresses and resizes images without sacrificing quality, ensuring faster page loads.
  3. Automated Deletion & Updates: Cloudinary's API allows dynamic updates and deletions, ensuring that old images do not remain stored unnecessarily.
  4. Secure & Scalable: Authentication and API security ensure that images are accessible only by authorized users.

Cloudinary Setup in CampusX

To integrate Cloudinary, we configure it using environment variables:

import { v2 as cloudinary } from "cloudinary";

cloudinary.config({
  cloud_name: process.env.CLOUDNARY_CLOUD_NAME,
  api_key: process.env.CLOUDNARY_APIKEY,
  api_secret: process.env.CLOUDNARY_SECRET,
});
Enter fullscreen mode Exit fullscreen mode

This setup ensures that our credentials remain secure and are not hardcoded into the source code.


Uploading Images to Cloudinary

Whenever a user uploads an avatar, cover image, or post image, the image is sent to Cloudinary’s storage, and the response contains a URL for accessing the uploaded image.

const uploadOnCloudnary = async (localfilepath) => {
  try {
    if (!localfilepath) {
      return null;
    }

    const response = await cloudinary.uploader.upload(localfilepath, {
      resource_type: "auto",
      folder: "home/learnDummy",
    });

    console.info("File uploaded :", response.url);
    return response;
  } catch (error) {
    console.log("Error while uploading to Cloudinary");
    fs.unlinkSync(localfilepath);
  }
};
Enter fullscreen mode Exit fullscreen mode

Updating User Avatars & Cover Images

When a user updates their avatar or cover image, the old one is deleted from Cloudinary before uploading the new one, preventing redundant storage.

const updateAvatar = async (oldCloudinaryUrl, localFilePath) => {
  try {
    if (!localFilePath) {
      return null;
    }

    const publicId = oldCloudinaryUrl?.split("/").pop().split(".")[0] || null;

    if (publicId) {
      await cloudinary.uploader.destroy(`home/learnDummy/${publicId}`);
      console.info("Old avatar deleted:", publicId);
    }

    const response = await cloudinary.uploader.upload(localFilePath, {
      resource_type: "auto",
      folder: "home/learnDummy",
    });

    console.info("New avatar uploaded:", response.url);
    return response;
  } catch (error) {
    console.error("Error updating avatar:", error);
    fs.unlinkSync(localFilePath);
    return null;
  }
};
Enter fullscreen mode Exit fullscreen mode

The same logic is applied to updating cover images:

const updateCoverImage = async (oldCloudinaryUrl, localFilePath) => {
  // Similar logic to updateAvatar
};
Enter fullscreen mode Exit fullscreen mode

Deleting Images

When a user deletes their profile or a post, associated images must also be deleted from Cloudinary to free up space.

const deleteImage = async (oldCloudinaryUrl) => {
  try {
    if (!oldCloudinaryUrl) {
      return null;
    }

    const publicId = oldCloudinaryUrl?.split("/").pop().split(".")[0] || null;

    if (publicId) {
      await cloudinary.uploader.destroy(`home/learnDummy/${publicId}`);
      console.info("Image deleted:", publicId);
    }

    return true;
  } catch (error) {
    console.error("Error deleting image:", error);
    return null;
  }
};
Enter fullscreen mode Exit fullscreen mode

Automating Image Cleanup with Mongoose Hooks

To ensure images are deleted when a user or post is removed, we use Mongoose pre-hooks.

postSchema.pre("deleteOne", { document: true, query: false }, async function (next) {
  console.log(`Deleting comments and image for post: ${this._id}`);
  await deleteImage(this.image);
  next();
});
Enter fullscreen mode Exit fullscreen mode

Whenever a post is deleted, the associated image is also deleted, preventing orphaned files from accumulating in Cloudinary.


Conclusion

By integrating Cloudinary in CampusX, we optimize image storage, improve load times, and automate media management. Cloudinary’s CDN ensures faster image delivery, while its API allows efficient handling of uploads, updates, and deletions. These optimizations contribute to an improved user experience, reduced server load, and seamless media management.

Top comments (0)

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay