Question
How can I preview an image selected through an <input type="file"> before uploading it? The preview must happen entirely in the browser, without using Ajax or sending the image to a server.
Short Answer
You will learn how browser file inputs expose selected files to JavaScript and how to display an image preview locally with URL.createObjectURL(). You will also learn to validate file types, clean up temporary Blob URLs, and handle the case where no file is selected.
Concept
A file input lets a user choose a file from their device:
<input type="file" accept="image/*">
Choosing a file does not upload it automatically. Instead, the browser makes information about the selected file available through the input element's files collection. JavaScript can use that local File object to create a temporary URL and assign it to an image element.
const file = fileInput.files[0];
const previewUrl = URL.createObjectURL(file);
image.src = previewUrl;
The image is read locally by the browser. No network request, Ajax request, or server code is required.
This matters because previews improve user experience: people can confirm that they selected the right profile picture, product image, attachment, or document before submitting a form. The actual upload can happen later, only after the user confirms the form.
Mental Model
Think of a selected file as a photo handed to the browser for inspection, not delivery. The browser has the photo temporarily in hand, but it has not mailed it to a server.
URL.createObjectURL(file) creates a temporary local label that an <img> element can use to find and display that photo. When the preview is no longer needed, remove the label with URL.revokeObjectURL().
File: the locally selected image- Blob URL: a temporary local address for that image
<img>: the frame that displays the image- Upload: a separate action that sends the image to a server
Syntax and Examples
Use the input's change event to detect a new selection. Get the first selected file from event.target.files, then use an object URL as the image source.
<label for="imageInput">Choose an image</label>
<input id="imageInput" type="file" accept="image/*">
<img id="preview" alt="Selected image preview" hidden>
<script>
const imageInput = document.querySelector('#imageInput');
const preview = document.querySelector('#preview');
imageInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (!file) {
preview. = ;
preview.();
;
}
imageUrl = .(file);
preview. = imageUrl;
preview. = ;
preview.(, {
.(imageUrl);
}, { : });
});
Step by Step Execution
Consider this example:
imageInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (!file) return;
if (!file.type.startsWith('image/')) {
alert('Please choose an image file.');
return;
}
const imageUrl = URL.createObjectURL(file);
preview.src = imageUrl;
});
- The user chooses a file in the operating system's file picker.
- The browser fires the input's
changeevent. event.target.files[0]retrieves the first selectedFileobject.- If the user cancelled the picker or cleared the field,
fileis missing and the function stops. file.type.startsWith('image/')checks whether the browser reports an image MIME type, such asimage/jpegorimage/png.
Real World Use Cases
- Profile photo forms: Let users verify their portrait before saving account changes.
- E-commerce dashboards: Preview a product photo before creating or updating a listing.
- Content management systems: Show article cover-image previews before an editor publishes.
- Support forms: Let users inspect an image attachment before submitting a support request.
- Image editing tools: Display a selected local image before applying client-side transformations such as cropping or resizing.
- Multi-file galleries: Render thumbnails for several selected images before the user chooses which ones to upload.
Real Codebase Usage
In production code, previews are usually combined with validation, state cleanup, and accessible feedback.
Validate early with guard clauses
function showPreview(file) {
if (!file) return;
if (!file.type.startsWith('image/')) {
throw new Error('Only image files are allowed.');
}
if (file.size > 5 * 1024 * 1024) {
throw new Error('The image must be 5 MB or smaller.');
}
return URL.createObjectURL(file);
}
Replace old preview URLs
If users select multiple files one after another, revoke the old URL before creating a new one.
let currentPreviewUrl = null;
imageInput.addEventListener('change', (event) => {
const file = event.target.[];
(currentPreviewUrl) {
.(currentPreviewUrl);
currentPreviewUrl = ;
}
(!file || !file..()) ;
currentPreviewUrl = .(file);
preview. = currentPreviewUrl;
preview. = ;
});
Common Mistakes
Trying to read the input's value as an image URL
This does not give JavaScript a usable local file path, and browsers intentionally restrict access to real paths for security.
// Do not rely on this.
preview.src = imageInput.value;
Use imageInput.files[0] and URL.createObjectURL() instead.
Forgetting that the user may cancel the picker
files[0] may be missing. Always check it first.
const file = event.target.files[0];
if (!file) return;
Trusting accept="image/*" as validation
The accept attribute filters the file picker but does not guarantee the selected file is safe or truly valid. Check file.type for user feedback, and validate again on the server when uploading.
Creating many Blob URLs without revoking them
Repeated calls to URL.createObjectURL() can retain memory until URLs are revoked or the page is unloaded. Revoke an old URL when replacing a preview, or revoke it after the image loads when it is no longer needed.
Comparisons
| Approach | Best use | Result | Notes |
|---|---|---|---|
URL.createObjectURL(file) | Displaying a local file in an image, video, or download link | Temporary Blob URL | Usually the simplest option for previews; revoke the URL when finished. |
FileReader.readAsDataURL(file) | When code specifically needs a Base64 data URL | data:image/...;base64,... string | Can be larger in memory; no manual object-URL cleanup. |
input.value | Identifying that an input has a selection | Browser-controlled string | Do not use it as a real local path or preview source. |
Uploading with fetch or form submission | Sending a file to a server | Network request | Not required for a client-side preview. |
Cheat Sheet
<input id="fileInput" type="file" accept="image/*">
<img id="preview" alt="Image preview" hidden>
const fileInput = document.querySelector('#fileInput');
const preview = document.querySelector('#preview');
let previousUrl;
fileInput.addEventListener('change', (event) => {
const file = event.target.files[0];
if (previousUrl) URL.revokeObjectURL(previousUrl);
if (!file || !file.type.startsWith('image/')) {
preview.hidden = true;
preview.removeAttribute('src');
;
}
previousUrl = .(file);
preview. = previousUrl;
preview. = ;
});
FAQ
Can JavaScript preview an image without uploading it?
Yes. Use the File selected from an <input type="file"> and assign an object URL to an <img> element. This happens entirely in the browser.
Does URL.createObjectURL() send the image to a server?
No. It creates a temporary local Blob URL inside the browser. It does not make a network request.
Should I use FileReader or URL.createObjectURL for image previews?
For a normal image preview, use URL.createObjectURL(). Use FileReader.readAsDataURL() when you specifically need a Base64 data URL.
Why can I not use the file input value as the image source?
Browsers do not expose a real local path to page JavaScript for security reasons. Use the files collection instead.
How do I limit the file picker to images?
Add accept="image/*" to the file input. Also validate file.type in JavaScript because accept is not a security boundary.
How do I preview multiple selected images?
Use input.files, loop through each File, create an object URL for each one, and create an element for every preview.
Mini Project
Description
Build a profile-image picker that previews a selected image without uploading it. The interface should reject non-image files, reject files larger than 2 MB, show a message for validation errors, and allow the user to remove the chosen image.
Goal
Create a local image preview that can be selected, validated, replaced, and removed entirely in the browser.
Requirements
Use a file input that guides users toward image files. Validate that the selected file is an image. Reject files larger than 2 MB and show an error message. Show the selected image only after it passes validation. Provide a button that clears the preview and selected file.
Keep learning
Related questions
Abort Ajax Requests with jQuery jqXHR.abort()
Learn how to cancel an in-progress jQuery Ajax request with jqXHR.abort(), handle abort status safely, and avoid stale UI updates.
Access the Correct this Inside a JavaScript Callback
Learn why JavaScript this changes in callbacks and how to preserve an object context using bind, arrow functions, and event handler patterns.
Add Key-Value Pairs to JavaScript Objects
Learn how to add key-value pairs to JavaScript objects with dot and bracket notation, dynamic keys, examples, and common mistakes.