Skip to main content

How to Save an Image to localStorage using JavaScript

localStorage provides a simple way to store key-value pairs in a user's browser, but it's designed for small amounts of string data, not for files. To store an image selected by a user, you must first convert it into a string format. The standard way to do this is by using the FileReader API to create a Base64-encoded Data URL.

This guide will teach you how to read a user-selected image file, convert it to a Data URL, and save it to localStorage. You will also learn about the critical storage limitations and why this approach is only suitable for very small images.

The Core Method: The FileReader API

Since localStorage can only store strings, we cannot save a File object directly. The FileReader API allows us to read the contents of a file asynchronously. We can use its readAsDataURL() method to convert an image into a Data URL, which is a very long string that represents the file's binary data.

The logic:

  1. Listen for the change event on an <input type="file"> element.
  2. When a file is selected, create a new FileReader instance.
  3. Define an onload event handler for the reader. This function will fire when the file has been successfully read.
  4. Inside onload, the reader's result property will contain the Base64 Data URL. Save this string to localStorage.
  5. Call reader.readAsDataURL() with the selected file to start the process.

Important Warning: The Limitations of localStorage

Before using this technique, you must understand its significant limitations:

  • Size Limit: localStorage has a strict storage limit, which is typically around 5 MB per domain across all major browsers. A single high-resolution photo can easily exceed this limit, causing the setItem() call to fail with a QuotaExceededError.
  • Performance: Converting a large file to a Base64 string is a CPU-intensive operation that can make your web page unresponsive. Storing and retrieving a multi-megabyte string also adds performance overhead.
  • Synchronous: localStorage is a synchronous API. Reading or writing large amounts of data can block the main thread, leading to a poor user experience.

Conclusion: This method is only suitable for very small images, like thumbnails or avatars. For larger images, you should use IndexedDB or store the image on a server.

Basic Example: Saving a Single Image

This example demonstrates the complete process of selecting, reading, and saving an image.

HTML:

<input type="file" id="image-input" accept="image/*">
<img id="retrieved-image" alt="Image from localStorage" style="width: 200px;">

JavaScript:

const imageInput = document.getElementById('image-input');

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

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

reader.onload = function(e) {
try {
// The result is the Base64 Data URL
const imageDataUrl = e.target.result;

// Save the string to localStorage
localStorage.setItem('savedImage', imageDataUrl);
console.log('Image saved to localStorage!');

// (See next section for how to retrieve and display it)

} catch (error) {
console.error('Error saving image to localStorage:', error);
alert('Storage limit exceeded! Please select a smaller image.');
}
};

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

How the FileReader Method Works

  1. new FileReader(): Creates a new reader object.
  2. reader.readAsDataURL(file): This is the command that starts the process. It reads the binary data of the File object asynchronously.
  3. reader.onload: This event handler is the most important part. It is a callback function that runs only after the entire file has been successfully read into memory.
  4. e.target.result: Inside the onload handler, this property contains the result of the read operation. For readAsDataURL(), this is a string that looks like data:image/png;base64,iVBORw0KGgo....

Retrieving and Displaying the Image

To get the image back from localStorage and display it, you use localStorage.getItem() and set the src attribute of an <img> element. Since the stored value is a valid Data URL, the browser knows how to render it directly.

Solution:

const retrievedImage = document.getElementById('retrieved-image');

// Get the Data URL string from localStorage
const savedImageDataUrl = localStorage.getItem('savedImage');

if (savedImageDataUrl) {
// Set the image src to the retrieved Data URL
retrievedImage.src = savedImageDataUrl;
console.log('Image loaded from localStorage.');
}
note

You can place this code anywhere you need to load the image, such as in a DOMContentLoaded event listener that runs when the page loads.

Conclusion

Using FileReader to convert an image to a Base64 Data URL is the standard way to store image data as a string.

  • The key is the asynchronous flow: reader.readAsDataURL(file) starts the process, and the logic to save the data must be placed inside the reader.onload event handler.
  • Crucially, this method is only appropriate for very small images due to the strict localStorage size limit (around 5 MB) and performance considerations.
  • For any application that needs to handle larger files or a significant number of images, a more robust client-side storage solution like IndexedDB is the professional choice.