How to Refresh an Image with a New One at the Same URL in JavaScript
When an image on a web page is updated on the server but keeps the same URL, the browser will often continue to display the old, cached version. To force the browser to download the fresh image, you need to "bust" the cache. The most common and effective way to do this is by appending a unique query string to the image's src attribute.
This guide will teach you the standard method for cache-busting an image using a timestamp. We will also cover an alternative, more advanced approach using the fetch API with specific cache headers.
The Core Problem: Browser Caching
To improve performance, browsers aggressively cache resources like images. When you request https://example.com/my-image.jpg, the browser downloads it and stores it locally. The next time it sees a request for the exact same URL, it will load the image from the local cache instead of re-downloading it from the server.
This becomes a problem if the image on the server has been updated but the URL hasn't changed. Your users will continue to see the old, stale version.
The Solution (Recommended): Cache Busting with a Query String
The simplest and most reliable solution is to make the URL unique every time you want to refresh the image. We can do this by appending a query parameter that changes on each request, typically a timestamp.
Problem: you have an image, and you need to force it to reload from the server when a user clicks a button.
<img id="my-image" src="https://picsum.photos/200" alt="A random image">
<button id="refresh-btn">Refresh Image</button>
Solution: this function updates the src attribute with a new timestamp, forcing the browser to treat it as a new URL.
const myImage = document.getElementById('my-image');
const refreshButton = document.getElementById('refresh-btn');
function refreshImage(imgElement) {
// 1. Get the base URL (without any existing query string)
const baseUrl = imgElement.src.split('?')[0];
// 2. Create a new, unique query string
const newTimestamp = Date.now();
// 3. Set the new src
imgElement.src = `${baseUrl}?t=${newTimestamp}`;
}
refreshButton.addEventListener('click', () => {
refreshImage(myImage);
console.log('Image refreshed. New URL:', myImage.src);
});
How Cache Busting Works
When you change an <img> element's src attribute, the browser initiates a new request for that URL.
- Original URL:
https://picsum.photos/200 - New URL:
https://picsum.photos/200?t=1677611000123
From the browser's perspective, these are two completely different URLs. The second URL is not in its cache, so it is forced to make a new network request to the server to download the resource. The Date.now() method is perfect for this because it returns the current timestamp in milliseconds, guaranteeing a unique value for every call.
An Advanced Alternative: Using fetch with cache: 'reload'
For more complex scenarios where you need finer control over the request, you can use the fetch API. This allows you to explicitly tell the browser to bypass the cache for a specific request.
Solution: this function fetches the image and then updates the src of all images that use that URL.
async function forceReloadImage(url) {
// 1. Fetch the image, telling the browser to bypass the cache.
await fetch(url, { cache: 'reload', mode: 'no-cors' });
// 2. Find all images on the page that use this URL.
const images = document.querySelectorAll(`img[src="${url}"]`);
// 3. "Jiggle" the src to force a re-render from the now-updated cache.
// This is necessary because the browser won't automatically re-render
// the image just because the cache was updated.
images.forEach(img => {
const originalSrc = img.src;
img.src = ''; // Temporarily clear the src
img.src = originalSrc; // Set it back
});
}
// Example Usage:
refreshButton.addEventListener('click', () => {
forceReloadImage(myImage.src);
});
Limitation: While powerful, this method is more complex. The cache-busting query string is simpler and sufficient for the vast majority of use cases.
Practical Example: Automatically Refreshing an Image
This is a common use case for things like security camera feeds or weather maps. The script uses setInterval to automatically refresh an image every 5 seconds.
const liveImage = document.getElementById('live-feed');
function refreshImage(imgElement) {
const baseUrl = imgElement.src.split('?')[0];
imgElement.src = `${baseUrl}?t=${Date.now()}`;
}
// Refresh the image every 5 seconds (5000 milliseconds)
setInterval(() => {
refreshImage(liveImage);
console.log('Live feed image refreshed.');
}, 5000);
Conclusion
Forcing a browser to reload an image is a matter of defeating its caching mechanism.
- The most common and recommended best practice is cache busting. This involves appending a unique query parameter (like a timestamp from
Date.now()) to the image'ssrcURL to make it appear new to the browser. - A more advanced alternative is to use the
fetchAPI with thecache: 'reload'option, but this is more complex and usually unnecessary. - Avoid simply re-setting
img.src = img.src. This will not work, as the browser will see the same URL and serve the image from its cache.