Building your first web app feels great. The code works. The layout looks clean. Your idea starts to feel real. Then you reach one feature that changes everything: Image upload. When a user selects an image with a standard file input, that file still lives on their device.
<input type="file" id="avatar-input">
Code language: HTML, XML (xml)
At this point, your app doesn’t have a real image URL yet. It only has access to a local file during that browser session. That’s fine for testing, but it doesn’t work for a real app. Your goal is to turn this local file into something your app can use anywhere.
Here’s the key difference between local and hosted:
- Local file. The image exists on only one device.
- Hosted asset. The image has a secure URL that your app can store, share, and display anywhere.
The goal is simple. We want to take a local image and turn it into a live hosted asset URL, like this:
https://res.cloudinary.com/your-cloud-name/image/upload/...
That URL can now be saved in a database, shown on a profile page, or shared across devices.
Building an uploader from scratch takes work. You need to handle file selection, validation, upload progress, API calls, error states, and previews. For a beginner project, that can feel like too much too soon.
The Cloudinary Upload Widget gives you a faster path. It provides a ready-made upload interface that sends files directly from the browser to the cloud.
This helps because:
- You don’t need a backend server.
- The widget supports drag and drop.
- It shows real-time upload progress.
- It returns a secure hosted URL after upload.
This allows you to focus on how a local file becomes a live asset.
For this demo, you’ll use:
- HTML and CSS
- Core JavaScript
- The Cloudinary Upload Widget
- An unsigned upload preset
You’ll need two Cloudinary values: your cloud name and an unsigned upload preset.
{note}Don’t use your API secret in the browser. The browser can see client-side code, so secrets should stay out of this project.{/note}
First, include the Cloudinary Upload Widget script via CDN.
<script
src="https://upload-widget.cloudinary.com/latest/global/all.js"
type="text/javascript"
></script>
Code language: HTML, XML (xml)
Then add a button to open the widget and an image tag to display the result.
<button id="upload_widget" class="cloudinary-button">Upload Image</button>
<div class="preview-area">
<img id="uploadedimage" src="" style="display: none;" />
</div>
Code language: HTML, XML (xml)
Now, connect the button to the widget logic. This is where the integration happens.
const myWidget = cloudinary.createUploadWidget(
{
cloudName: "your_cloud_name",
uploadPreset: "ml_beginners_preset",
},
(error, result) => {
if (!error && result && result.event === "success") {
const liveUrl = result.info.secure_url;
const imgTag = document.getElementById("uploadedimage");
imgTag.src = liveUrl;
imgTag.style.display = "block";
}
}
);
document.getElementById("upload_widget").addEventListener(
"click",
() => {
myWidget.open();
},
false
);
Code language: JavaScript (javascript)
The important part is the liveUrl. That is the exact moment the local file becomes a hosted asset.
After the upload succeeds, Cloudinary returns a URL starting with https://res.cloudinary.com/. This is no longer a local file. It is now a hosted asset that can load in your app from anywhere.
You can save this URL in tools like Supabase, Firebase, or MongoDB. The user selects a file once, and your app gets a URL it can keep using forever.
The best way to understand this is to try the demo yourself.
- Live Demo: Getting Started with Cloudinary
- Source Code: GitHub Repo: cloudinary-masterclass
Watch the full upload flow:
You’ve now built a simple image upload flow with Core JavaScript and Cloudinary. You started with a local file, used the widget to send it to the cloud, and received a secure hosted URL.
This URL can now power real features like profile images, product photos, or image galleries. Ready to start building media-rich web apps? Sign up for a free Cloudinary account today.
What is the difference between a local file and a hosted asset?
A local file exists only on the specific device where it was created. A hosted asset is stored on a cloud server like Cloudinary and assigned a permanent URL, which makes it accessible from any device or browser.Why should beginners use the Cloudinary Upload Widget?
The widget manages complex technical tasks like file validation, drag and drop, and upload progress. This allows developers to build a working upload feature without having to set up a backend server or manage infrastructure.Is it safe to use Cloudinary in a frontend JavaScript project?
It is safe if you use Unsigned Upload Presets. These presets allow you to send files directly from the browser to Cloudinary without exposing your private API Secret in your client side code.What information does Cloudinary return after a successful upload?
Cloudinary returns a result object that includes a secure URL for the uploaded file. This link can be used immediately to display the image on a page or saved to a database like Supabase for later use.Can I transform images immediately after they are uploaded?
Yes. Since the file is now a hosted asset, you can apply dynamic transformations such as resizing, cropping, or blurring. You do this by adding specific parameters directly to the hosted URL provided by Cloudinary.