Skip to content

Instantly share code, notes, and snippets.

@1travelintexan
Created December 13, 2024 07:41
Show Gist options
  • Save 1travelintexan/721f41df2b86862b007aaf47065f2bd4 to your computer and use it in GitHub Desktop.
Save 1travelintexan/721f41df2b86862b007aaf47065f2bd4 to your computer and use it in GitHub Desktop.

1. Cloudinary account setup

Go to this link https://cloudinary.com/ and create your cloudinary account, verify your email and go through or skip the initial questions

After you are done you should be able to see the following in your dashboard:

  • Cloud Name
  • API key
  • API Secret

These 3 elements are unique to you and will need them to use cloudinary. You will need to add them to your .env file.

In your .env file:

CLOUD_NAME=<your-cloudinary-name>
CLOUD_API_KEY=<your-cloudinary-key>
CLOUD_API_SECRET=<your-cloudinary-secret>

Make sure you have the correct .env syntax. You don't need to use quotes for the strings.

2. Package installation

Install the following 3 npm packages: cloudinary, multer by running the following code in your terminal

npm i cloudinary multer

3. Cloudinary config setup

Create a file in the middlewares folder called cloudinary.config.js and add the following code:

// the following 3 packages are needed in order for cloudinary to run
const cloudinary = require("cloudinary").v2;
const multer = require("multer");

// your three cloudinary keys will be passed here from your .env file
cloudinary.config({
  cloud_name: process.env.CLOUD_NAME,
  api_key: process.env.CLOUD_API_KEY,
  api_secret: process.env.CLOUD_API_SECRET,
});

const storage = multer.diskStorage({
  filename: function (req, file, cb) {
    cb(null, file.originalname);
  },
});

module.exports = multer({ storage }); 

4. Frontend setup

Make sure in your frontend you have a form with the following specifications This is the function to call on submit of form

  //multiple images function
  async function handleImages(e) {
    //prevent the form from reloading
    e.preventDefault();
    //create formData (multer on the server expects form data)
    const myFormData = new FormData();
    // Change the images state to an array so we can call the .forEach( ) on it
    //for each image, add it to the form data
    Array.from(images).forEach((image) => {
      myFormData.append("imageUrl", image);
    });
    try {
      const { data } = await axios.post(
        "http://localhost:5005/auth/multiple-uploads",
        myFormData
      );
      console.log("image uploaded successfully", data);
      nav("/home");
    } catch (error) {
      console.log(error);
    }
  }

4. Frontend setup

This is what the form should look like, make sure to add the multiple attribute to the input

 <form onSubmit={handleImages}>
        <label>
          Change Profile Image:
          <input
            type="file"
            name="image"
            multiple
            onChange={(e) => setImages(e.target.files)}
          />
        </label>
        <button>Submit</button>
      </form>

IMPORTANT:

  • the action "/multiple-uploads" can be different but needs to match your route url. See next section.
  • the input name "imageUrl" can be different but needs to match the targeted name in your route. See sext section.

5. Cloudinary route handle

Go to the post route where you want to receive an image/file to store in cloudinary.

Asides from your regular require (express, routes, models) require your cloudinary.config.js by adding the following line:

This is how your route should look like:

//We will need this variable to upload each image one by one
const cloudinary = require("cloudinary").v2;
//middleware to send image to cloudinary
const uploader = require("../middlewares/cloudinary.config");
//uploader.array will accept an array of images with the key imageUrl
router.post(
  "/multiple-uploads",
  uploader.array("imageUrl"),
  async (req, res) => {
    //the images after the uploader will be in the request . files
    const images = req.files;
    // create an array to push the urls into after we add them to the cloud
    const imageUrls = [];
    //for in loop to loop over the object of images
    for (const image of images) {
      // await the uploader.upload from cloudinary to get the  secure url
      const result = await cloudinary.uploader.upload(image.path, {
        resource_type: "auto",
      });
      //push into the array the secure url on each iteration
      imageUrls.push(result.secure_url);
    }
    if (!imageUrls.length) {
      console.log("there is no file");
      res.status(403).json({ message: "there is no file" });
    } else {
      res.status(200).json({ message: "success!", imageUrls });
    }
  }
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment