Upload Image to Cloudinary
The uploadImagesToCloudinary
utility simplifies the Cloudinary image upload process, offering range of configuration options and prompt error detection with clear messaging.
Let's first dive into an example. Afterward, we'll delve deeper into the syntax and configuration options of the uploadImagesToCloudinary
utility:
// import express and anything else that you need
// import "uploadImagesToCloudinary" from 'express-cloudinary-image-handler'
const app = express()
app.post('/upload-images', async (req, res) => {
try {
const upload_report = await uploadImagesToCloudinary({
req: req,
configuration: {
formDataFieldName: 'productImages',
cloudinaryFolderName: 'product',
allowedExtensions: ['png', 'jpg', 'jpeg'], // Optional
maxFileSizeInKB: 512, // Optional
maxNumberOfUploads: 10, // Optional
deleteAllTempFiles: true // Optional
}
})
if (upload_report.isError) {
return res.json({
status_code: upload_report.errorInfo.statusCode,
message: upload_report.errorInfo.message
})
}
return res.json({
message: 'Uploaded Images Successfully',
info: {
uploaded_images_info: upload_report.imagesInfo
}
})
}
catch (error) {
return res.json({ message: "Something went wrong" });
}
})
uploadImagesToCloudinary - Parameters
Parameter Name | Type | Requirement | Description |
---|---|---|---|
req | object | Required | The Express request object. |
configuration | object | Required | Configuration options for the upload. |
configuration
Object Properties:
Property Name | Type | Requirement | Description |
---|---|---|---|
formDataFieldName | string | Required | The field name used in the frontend's FormData object for sending the image files to the backend. |
cloudinaryFolderName | string | Required | The folder name in Cloudinary where the image will be stored. |
allowedExtensions | array | Optional | List of allowed file extensions for the image. |
maxFileSizeInKB | number | Optional | Maximum allowed file size for the image in kilobytes. |
maxNumberOfUploads | number | Optional | Maximum number of images that can be uploaded at once. |
deleteAllTempFiles | boolean | Optional | Details |
uploadImagesToCloudinary - Return Value
Field Name | Type | Description |
---|---|---|
isError | boolean | Indicates if there was an error during the upload. |
errorInfo | object | Contains error details if isError is true. |
imagesInfo | array | Array containing information about each uploaded image. |
errorInfo
Object Properties:
Property Name | Type | Description |
---|---|---|
statusCode | number | The status code of the error. |
message | string | The error message. |
imagesInfo
is an array of objects, where each object represents details about an uploaded image. Properties of each object:
Property Name | Type | Description |
---|---|---|
imageSrc | string | The direct URL or source of the uploaded image, which can be used to display or access the image. |
imagePublicId | string | The unique identifier provided by Cloudinary for the image. This ID is essential for delete operation. |
uploadImagesToCloudinary - Multiple Instances
In some scenarios, you may need to use the uploadImagesToCloudinary
utility more than once within the same controller.
To do this effectively, you should set the deleteAllTempFiles
property to false
. This ensures that image files uploaded under different field names are not deleted after the first instance completes its operation.
Here's an example:
// import express and anything else that you need
// import "uploadImagesToCloudinary" from 'express-cloudinary-image-handler'
const app = express()
app.post('/upload-product-images', async (req, res) => {
try {
// First Instance: Upload Main Product Display Images
const featuredImagesUploadReport = await uploadImagesToCloudinary({
req: req,
configuration: {
formDataFieldName: 'featuredImages',
cloudinaryFolderName: 'product',
allowedExtensions: ['png', 'jpg', 'jpeg'],
maxFileSizeInKB: 512,
maxNumberOfUploads: 10,
deleteAllTempFiles: false // Important
}
})
// Handle errors for the first instance
if (featuredImagesUploadReport.isError) {
return res.json({
status_code: featuredImagesUploadReport.errorInfo.statusCode,
message: featuredImagesUploadReport.errorInfo.message
})
}
// Second Instance: Upload Product Detail/Angle Images
const productImagesUploadReport = await uploadImagesToCloudinary({
req: req,
configuration: {
formDataFieldName: 'productImages',
cloudinaryFolderName: 'product',
allowedExtensions: ['png', 'jpg', 'jpeg'],
maxFileSizeInKB: 512,
maxNumberOfUploads: 10,
deleteAllTempFiles: true // Now it's safe to delete
}
})
// Handle errors for the second instance
if (productImagesUploadReport.isError) {
return res.json({
status_code: productImagesUploadReport.errorInfo.statusCode,
message: productImagesUploadReport.errorInfo.message
})
}
// Success Response
return res.json({
message: 'Uploaded Images Successfully',
info: {
featuredImages: featuredImagesUploadReport.imagesInfo,
productImages: productImagesUploadReport.imagesInfo
}
})
}
catch (error) {
return res.json({ message: "Something went wrong" })
}
})
In this example, the first instance uploads main product display images with the field name featuredImages
and the second instance uploads product detail or angle images with the field name productImages
. The deleteAllTempFiles
property is set to false
in the first instance to retain the images for the second instance. In the second instance, it's set to true
to clean up all temporary files after the operation is complete.
deleteAllTempFiles
Property - Details
The deleteAllTempFiles
is a property within the configuration
parameter. It's optional, and its default value is set to true
.
What It Does
This property controls the cleanup behavior for files temporarily stored in the server's "temp" folder during the upload process.
-
When
true
: All files in the "temp" folder associated with the current upload operation, irrespective of their field names, are automatically deleted after the upload is complete. This ensures a clean temporary storage specific to the current operation, free from any residual files. -
When
false
: The utility will delete all image files that match the name set informDataFieldName
and any non-image files from the "temp" folder. However, it will retain image files that have different field names than the one specified informDataFieldName
.
Use Cases
-
Set to
true
: Use this setting when you're uploading a batch of images in one go and want to ensure that the temporary storage is completely cleared afterward, leaving no leftover or unwanted files. -
Set to
false
: Opt for this when you have multiple separate upload operations within the same controller. It ensures that files required for subsequent operations aren't mistakenly deleted by earlier tasks.
Naming Images in Cloudinary: Use Original Source File Name or Manually Set the Name
Is this seciton for you?
-
In prior sections, discussions regarding file naming were put aside, as image names in cloudinary were generated automatically.
-
With image names produced through the automatic process, you find out the image's name only after its upload.
-
However, if you need to determine the image's name before sending it to Cloudinary, this section is for you.
We've touched on the uploadImagesToCloudinary
function, which requires a configuration
parameter. This parameter is an object composed of several properties. All of these properties have been previously explained, except one: the useSourceFileName
property.
This property is optional, accepting a boolean value with a default of false.
When set to true
, the property allows the original source file name to be used as the Cloudinary image file's name.
Manually Set the Name
While using useSourceFileName
, we can also manually set Name. This can be achieved by manipulating the frontend's FormData. Specifically, by providing a third parameter to the FormData, you can set the desired name for the image.
For instance:
formData.append('image', 'image_file', 'desired_image_name');
In this example, desired_image_name
will be the name assigned to the image when it's uploaded to Cloudinary.
Ensuring Unique File Names
One of the primary concerns of using the original file name is the potential risk of overwriting an existing image in Cloudinary. If a new image, bearing the same name as an existing one, is uploaded, the older image will be replaced. This can lead to unintentional replacements and potential data loss.
To mitigate the risk of overwriting files in Cloudinary due to name collisions, it's advisable to ensure that each file name is unique. One effective way to achieve this is by leveraging packages like nanoid
to generate a unique identifier for each file. By appending or prepending this unique ID to the original file name, the chances of having two files with the same name become extremely low.
For example:
import { nanoid } from 'nanoid';
// Generate a unique ID
const uniqueID = nanoid();
// Append the unique ID to the original file name
const uniqueFileName = `${uniqueID}_${image_info.img_file.name}`;
formData.append('image', image_name, uniqueFileName);
By adopting this approach, you not only retain the advantage of pre-determining the image's name before uploading but also ensure that each image has a distinct name, safeguarding against unintentional overwrites.