Image uploads are a common feature in modern web apps, whether you're building a social media platform, profile dashboard, or product gallery. In this tutorial, you'll learn how to upload and preview images using React and Cloudinary, a cloud-based media management platform.
β What Will You Learn?
-
Set up a React app
-
Use Cloudinary to host uploaded images
-
Preview selected images before uploading
-
Upload images to Cloudinary using an API
-
Manage state and display uploaded images in your app
π Step 1: Create a Cloudinary Account
If you don’t already have one, go to https://cloudinary.com and sign up.
Once signed up:
-
Go to your Dashboard
-
Copy these credentials:
-
Cloud name
-
API key
-
API secret
-
We'll use only the Cloud name for client-side uploads using unsigned presets.
π Step 2: Set Up an Unsigned Upload Preset
-
Go to Settings > Upload tab.
-
Scroll down to Upload presets
-
Click on Add upload preset
-
Enable Unsigned
-
Name it something like
react_unsigned
-
Click Save
βοΈ Step 3: Create a New React App
You can use create-react-app
to bootstrap your project.
npx create-react-app react-cloudinary-upload
cd react-cloudinary-upload
npm start
Step 4: Install Axios
We'll use axios
to make HTTP requests to Cloudinary.
npm install axios
Step 5: Create the Upload Component
Create a new file: UploadImage.js
import React, { useState } from 'react';
import axios from 'axios';
const UploadImage = () => {
const [selectedImage, setSelectedImage] = useState(null);
const [previewUrl, setPreviewUrl] = useState('');
const [uploadedImageUrl, setUploadedImageUrl] = useState('');
// Preview the selected image
const handleImageChange = (e) => {
const file = e.target.files[0];
setSelectedImage(file);
setPreviewUrl(URL.createObjectURL(file));
};
// Upload to Cloudinary
const handleUpload = async () => {
if (!selectedImage) return;
const formData = new FormData();
formData.append('file', selectedImage);
formData.append('upload_preset', 'react_unsigned'); // Your unsigned preset
try {
const res = await axios.post(
'https://api.cloudinary.com/v1_1/<your_cloud_name>/image/upload',
formData
);
setUploadedImageUrl(res.data.secure_url);
} catch (err) {
console.error('Upload error:', err);
}
};
return (
<div style={{ textAlign: 'center' }}>
<h2>Upload and Preview Image</h2>
<input type="file" onChange={handleImageChange} accept="image/*" />
<br /><br />
{previewUrl && (
<div>
<h4>Preview:</h4>
<img src={previewUrl} alt="Preview" width="300" />
</div>
)}
<br />
<button onClick={handleUpload}>Upload to Cloudinary</button>
{uploadedImageUrl && (
<div>
<h4>Uploaded Image:</h4>
<img src={uploadedImageUrl} alt="Uploaded" width="300" />
</div>
)}
</div>
);
};
export default UploadImage;
Explanation of Code
β useState
We use it to manage:
-
selectedImage
– the actual image file -
previewUrl
– preview URL usingURL.createObjectURL
-
uploadedImageUrl
– final image URL returned from Cloudinary
β handleImageChange
Fired when the user selects an image. It sets both:
-
File object for upload
-
Temporary preview URL
β handleUpload
This function sends the image to Cloudinary:
-
Appends image and preset to
FormData
-
Sends POST request to Cloudinary API
-
Saves the returned URL for display
πΌοΈ Step 6: Use the Component in App.js
Update your App.js
file:
import React from 'react';
import UploadImage from './UploadImage';
function App() {
return (
<div className="App">
<UploadImage />
</div>
);
}
export default App;
Output
When you run the app:
-
You can choose an image file
-
You’ll see its preview immediately
-
After clicking upload, it will be hosted on Cloudinary
-
The uploaded image URL will be displayed
π‘οΈ Best Practices
-
Only use unsigned uploads for non-sensitive use cases. Use server-side API with API secret for production.
-
Validate file types and size before upload.
-
Handle loading state and errors for better UX.
π Conclusion
With just a few steps, you’ve now integrated image upload and preview in a React app using Cloudinary. This is great for user profiles, product images, blog thumbnails, and much more.