Skip to main content

How to Preview an Image Before Uploading in JavaScript

Providing users with an instant preview of the image they've selected is a crucial feature for a good user experience. It confirms their selection and allows them to see what they are about to upload. The most efficient and modern way to achieve this is by using the URL.createObjectURL() method, which generates a temporary, local URL for the selected file.

This guide will teach you how to use URL.createObjectURL() to preview a single image and multiple images. We will also briefly cover the alternative FileReader API and explain why createObjectURL is generally the better choice for this specific task.

The Core Method: URL.createObjectURL()

The URL.createObjectURL() method is the best tool for this job. It takes a File object (which you get from an <input type="file">) and creates a special blob: URL that points to the file's data in the browser's memory. This process is synchronous and very fast, as it doesn't involve reading the entire file into a new format.

The logic:

  1. Add a change event listener to the file input element.
  2. When a file is selected, access it from the input's files property.
  3. Call URL.createObjectURL() with the File object.
  4. Set the src attribute of an <img> element to the newly created URL.

Basic Example: Previewing a Single Image

This example shows the standard implementation for a single file preview.

HTML:

<input id="file-input" type="file" accept="image/*">
<img id="preview-image" src="" alt="Image preview" style="display: none; width: 200px;">
note

The accept="image/*" attribute is a helpful hint to the browser to filter for image files in the file selection dialog.

JavaScript:

const fileInput = document.getElementById('file-input');
const previewImage = document.getElementById('preview-image');

fileInput.addEventListener('change', function() {
const file = this.files[0];

if (file) {
// Create a temporary URL for the selected file
const objectURL = URL.createObjectURL(file);

// Set the image src to the temporary URL
previewImage.src = objectURL;
previewImage.style.display = 'block';

// Optional: Release the object URL after the image has loaded
previewImage.onload = function() {
URL.revokeObjectURL(objectURL);
}
} else {
// Hide the preview if no file is selected
previewImage.src = '';
previewImage.style.display = 'none';
}
});
note

URL.revokeObjectURL() is a good practice for freeing up browser memory once the object URL is no longer needed.

Previewing Multiple Images

To handle multiple files, you add the multiple attribute to your file input. The logic is similar, but you loop through the FileList object.

HTML:

<input id="multi-file-input" type="file" accept="image/*" multiple>
<div id="previews-container"></div>

JavaScript:

const multiFileInput = document.getElementById('multi-file-input');
const previewsContainer = document.getElementById('previews-container');

multiFileInput.addEventListener('change', function() {
// Clear any existing previews
previewsContainer.innerHTML = '';

for (const file of this.files) {
const img = document.createElement('img');
img.style.width = '150px';
img.style.margin = '5px';

const objectURL = URL.createObjectURL(file);
img.src = objectURL;

img.onload = function() {
URL.revokeObjectURL(objectURL);
}

previewsContainer.appendChild(img);
}
});

An Alternative (Less Efficient) Method: The FileReader API

The FileReader API is another way to achieve this. Instead of creating a direct reference to the file in memory, it reads the entire file's content into a Base64-encoded Data URL.

For example, while this works, it is less performant, especially for large images. It consumes more memory and takes longer because the entire file has to be read and encoded into a string.

fileInput.addEventListener('change', function() {
const file = this.files[0];

if (file) {
const reader = new FileReader();

reader.onload = function(e) {
// e.target.result contains the Base64 Data URL
previewImage.src = e.target.result;
previewImage.style.display = 'block';
};

// Start the asynchronous read operation
reader.readAsDataURL(file);
}
});
note

For the simple task of previewing an image, URL.createObjectURL() is synchronous and more efficient. FileReader is better suited for when you need the actual file content as a string, such as for uploading to an API that expects a Base64 payload.

Conclusion

Providing an image preview is a simple yet impactful user experience improvement.

  • The URL.createObjectURL() method is the recommended best practice for creating image previews. It is fast, efficient, and uses minimal memory.
  • Remember to use URL.revokeObjectURL() in the image's onload event to free up browser resources.
  • While the FileReader API also works, it is less performant for this specific task and should be reserved for when you need the file's content as a Base64 string.