Snug Gallery / Guides

Replaced an image in Shopify but the old one still shows?

Since April 2026 Shopify no longer purges a replaced file from its CDN. Why the old image sticks, how to tell CDN cache from browser cache, and the fix.

You replaced a photo in Content > Files, refreshed the storefront, and the old one is still there. You cleared your browser cache. Still there. Opened the page on your phone. Still the old image. This is not your theme being slow and it is not Shopify being broken; it is a deliberate change to how Shopify's CDN treats replaced files, and once you know the rule the fix takes a minute.

What changed in April 2026

On April 7, 2026 Shopify stopped purging a file's CDN URL when you replace or delete the file in the admin. Before that date, replacing cat.jpg in Files pushed the new image to every edge server within minutes. Now the old content keeps being served from cdn.shopify.com until the cached copy's time-to-live runs out, which can be a long time for images. Shopify's own note says the change was made to reduce purge volume and keep behaviour consistent across its edge providers. The announcement is at Replacing or deleting a Shopify-hosted file no longer purges its CDN URL.

The important detail is in what Shopify recommends instead: render file references with the platform's URL helpers so the current versioned URL is emitted. Every image URL Shopify generates through Liquid ends in a ?v= parameter, a number that changes whenever the file changes. A versioned URL is a brand-new address to the CDN, so it is never served from an old cache. A URL without the version, or with an old version pasted in by hand, points at whatever the CDN remembers.

In other words the behaviour is now the same as every other CDN on the internet: the content behind a fixed URL is cached, and if you want fresh content you need a fresh URL. Shopify's theme filters have always produced fresh URLs; what disappeared is the safety net that used to cover the places where people had hard-coded the address.

Where the old image is hiding

Start by finding out where the stale URL lives, because the fix is different for each. Open the page, right-click the old image and choose Open image in new tab. Look at the address.

  1. If the URL ends in ?v= followed by a number, and the number is the same as before you replaced the file, the page itself is serving an old reference. That usually means the image is coming from a cached page rather than a cached file; wait a few minutes, or republish the page, and it will refresh.
  2. If the URL has no ?v= at all, someone pasted a raw cdn.shopify.com address into a product description, a blog post, a page's HTML, a theme setting that takes free text, or a custom Liquid section. That address will keep returning the original image for as long as the CDN holds it. Shopify's note is explicit that hardcoded URLs in descriptions, blog posts, theme code and printed materials are affected.
  3. If the URL is the right version and the image is still old, the problem is on your side of the wire: your browser or a corporate proxy cached the image. A hard refresh or an incognito window settles it. Check on a different network before you conclude anything else.
  4. If you used Rename instead of Replace, the file's URL handle changed and the old address stops working entirely, so you will see a broken image rather than an old one. Shopify's files documentation describes the difference: Replace keeps the name and URL handle, Rename changes the URL and the previous one no longer works.

Fixing a hard-coded URL

  1. In a product description or blog post, delete the pasted image and insert it again through the editor's image button. The editor stores a file reference, and Shopify renders the current versioned URL every time the page is served. Pasting an <img src="https://cdn.shopify.com/..."> tag into the HTML view is the pattern to avoid.
  2. In a theme section, change the setting type from text to image_picker if you control the schema, and reference it in Liquid with image_url. If you are using someone else's theme and the field only accepts a URL, upload the replacement as a new file with a new name and paste the new address. You lose the convenience of Replace, but the image updates immediately.
  3. In a custom Liquid snippet, replace any literal URL with the asset_url, file_url or image_url filter against the file or setting it belongs to. These are the three filters Shopify names in the announcement, and all three emit the version parameter.
  4. In email templates, Google Merchant Center feeds and anything printed, there is no filter to help you. Treat a replaced file as a new file: upload it under a new name and update the reference. A feed that points at cdn.shopify.com without a version will show Google the old photo until the cache expires.

Why gallery apps are the usual suspect

Image-heavy apps are where this bites hardest, because they handle hundreds of files and because many of them were built to copy a URL once and store it. If a gallery app fetched the address of your photo when you added it, saved that string in its own database, and prints it into the page on every view, it is serving exactly the kind of fixed URL the change affects. Replace the photo in Files and the gallery will show the old one indefinitely, and the app has no way of knowing. The same goes for apps that re-host your images on their own servers, which we cover in Shopify Files vs app-hosted images.

Snug Gallery does not store URLs. A gallery item is a Shopify metaobject holding a reference to a file in your store's Files; the storefront block is a theme app extension that renders that reference through Liquid, calling image_url with the width it needs for each slot and for each srcset candidate. Shopify computes the URL at render time, including the current version, so the CDN sees a new address the moment the file changes. The lightbox image at 2048 px and the small product-card thumbnails in Shop the look go through the same filter.

The admin side works the same way. The editor's thumbnails are requested from the Admin API when you open a gallery, with the size baked into the request, rather than read back from anything the app saved earlier. When you use Replace on an item inside the Snug editor, the app uploads the new file, points the item at it and deletes the file it was pointing at before, which is a cleaner outcome than a same-named replacement anyway: nothing anywhere still refers to the old file.

The one place you can still trip is the file itself. If you replace an image in Content > Files and the new version is a different aspect ratio, the gallery will show it correctly, but the focal point and any Shop the look hotspots you set were positioned against the old picture. Check pins after a replacement that changes the crop.

A quick test you can run today

  1. Pick an image that appears in two places: once in a gallery block and once pasted into a page or product description.
  2. In Content > Files, click Replace on it and upload an obviously different picture of the same format.
  3. Reload the storefront in an incognito window. The gallery block should show the new picture straight away; the pasted copy will probably still show the old one.
  4. Open the pasted image in a new tab and compare the URL with the gallery's. The missing or outdated ?v= is the whole story, and it tells you exactly which content on your store needs re-inserting.

What to do about the pages you cannot fix

If a hard-coded URL is somewhere you cannot easily change, such as an old newsletter or a QR code on packaging, the honest answer is that it will show the old image until the CDN's cached copy expires, and Shopify does not publish how long that is or offer a manual purge. Plan for it: when an image is going to be referenced from outside Shopify, upload it under a dated or versioned filename (hero-2026-10.jpg) so a future replacement is a new upload and a new link rather than a Replace. Inside the storefront, let the filters do their job and the problem does not exist.

Faster, correct image updates are also a small speed win. Versioned URLs can be cached by the browser for a very long time without any risk of staleness, which is part of why the lazy-loading and sizing advice in our Core Web Vitals guide works as well as it does. Snug Gallery is free to install, stores every image in your own Files, and renders each one through Shopify's own filters, so replacing a photo means replacing it once.

Frequently asked questions

Why does my Shopify store still show the old image after I replaced the file?

Since April 7, 2026 Shopify no longer purges a replaced or deleted file's URL from its CDN. Anything that references the file through Liquid filters gets a new versioned URL and updates at once; anything with a pasted cdn.shopify.com address keeps showing the cached old image until the cache expires.

How do I force Shopify's CDN to refresh an image?

You cannot purge it yourself. Either re-insert the image through an editor or filter that emits the ?v= version parameter, or upload the new picture as a new file with a new name and update the reference. Clearing your browser cache only helps if the URL already carries the new version.

Is the problem my theme or my gallery app?

Open the stale image in a new tab. If the URL has no ?v= parameter, the component printing it stored a fixed URL. Themes that use image_url are fine; apps that save file URLs in their own database or re-host your images are the usual cause. Snug Gallery renders file references through Liquid at request time and is not affected.

Does replacing an image in Shopify Files change its URL?

Replace keeps the file name and URL handle but changes the version parameter that Shopify's filters append. Rename changes the URL handle itself, and the previous URL stops working. Neither purges the CDN's cached copy of the old address.

More guides