Shopify product image
not loading.
Main product image or thumbnails show a blank space, a broken image icon, or load indefinitely. Five likely causes below, ranked by frequency, with the fix for each and a 30-second console diagnostic.
Symptoms
- Infinite loading spinner or blank space on the main product image.
- Clicking variant thumbnails changes the border or active state, but the main photo doesn't swap.
- Image collapses vertically to 0px height, squeezing or hiding content completely.
- Images load only after scrolling the page slightly, remaining blank on initial viewport render.
30-second diagnostic
Run this in the browser console on the broken product page. The output reveals whether native lazy loading is colliding with an old Javascript theme library or collapsing parent sizes.
// Jelonyx · Shopify product image diagnostic
// Paste into devtools console on a product page.
// Watches for image elements, checks lazy-loading configurations and visibility.
(() => {
const images = document.querySelectorAll('main img, .product-media img, [class*="product"] img');
console.group('%c[jlx] product image checker', 'color:#B8D67A;font-weight:600');
console.log('total images found:', images.length);
let issuesFound = 0;
images.forEach((img, i) => {
const isLazy = img.getAttribute('loading') === 'lazy';
const src = img.getAttribute('src');
const dataSrc = img.getAttribute('data-src') || img.getAttribute('data-srcset');
const parent = img.parentElement;
const parentHeight = parent ? parent.clientHeight : 0;
console.group(`img #${i} - ${img.className || 'no-class'}`);
console.log('src:', src);
console.log('data-src/srcset:', dataSrc);
console.log('loading attribute:', isLazy ? 'lazy (native)' : 'not lazy');
console.log('parent element clientHeight:', parentHeight + 'px');
if (isLazy && dataSrc && !src) {
console.warn('⚠️ POSSIBLE CONFLICT: Native loading="lazy" is on, but src is missing (deferred to lazy-load script). This can stall loading.');
issuesFound++;
}
if (parentHeight === 0) {
console.warn('⚠️ ZERO HEIGHT parent: Image container collapses to 0px height. Native loading="lazy" will NOT load it because it is out of viewport!');
issuesFound++;
}
console.groupEnd();
});
console.log(`Diagnostic finished. Issues flagged: ${issuesFound}`);
console.groupEnd();
})();Most likely causes, ranked
- 01Lazy-loading script collision.
Native browser lazy loading (
loading="lazy") conflicts with an older theme or app lazy-load library (e.g. lazysizes, lozad). The image has nosrcattribute and waits for JS, but the script never fires because of a JS crash.Fix: Remove custom JS lazyload scripts from the theme. Standardize on native Shopify responsive filters and browser lazy loading. Swap data-src selectors for clean native src attributes.
- 02Missing aspect ratio CSS wrapper.
The image has native loading but the parent container collapses to 0 height before load. The browser thinks the image is out of view (or tiny), so it never triggers the lazy loader.
Fix: Implement an explicit aspect-ratio wrapper. Set a padding-bottom percentage based on the image aspect ratio or use CSS grid parameters so the browser reserves layout space before download.
- 03Unescaped attributes breaking HTML slideshow markup.
Liquid parameters (like
image.alt) contain double quotes or unescaped characters, breaking the surrounding slider configuration script attributes.Fix: In theme files (e.g.,
main-product.liquid), wrap image alt attributes in the escape filter:image.alt | escape. - 04JavaScript exception halts slideshow gallery init.
A third-party app (like a custom tab or review widget) throws an uncaught JavaScript error on page load, stopping the theme's product media gallery script before it can initialize.
Fix: Check browser console errors (F12). Locate and patch the failing JS block, or wrap the conflicting code in a safe try/catch block.
- 05Shopify CDN caching synclag.
A product image file was replaced in Admin with the exact same filename. The browser requests the file but the CDN delivers a stale or broken cache file.
Fix: Rename the image file locally (e.g. adding a unique version suffix like -v2) and upload it to Shopify. Liquid resolves the updated CDN URL natively.
Responsive aspect-ratio fix (causes #1, #2)
This snippet renders an image using native browser lazy loading while maintaining correct sizing and responsive bounds to prevent layout shifts.
{% comment %}
Jelonyx · Product image container utility
Ensures container maintains correct aspect ratio to prevent layout collapse
and lazy loading failures. Correctly binds responsive srcset attributes.
Source: jelonyx.com/shopify/fix/image-not-loading
{% endcomment %}
{%- if image != blank -%}
<div class="jlx-img-wrapper" style="position: relative; width: 100%; padding-bottom: {{ 1 | divided_by: image.aspect_ratio | times: 100 }}%; overflow: hidden; background: var(--bg-secondary, #171922); border-radius: 4px; border: 1px solid var(--rule-strong, #1f222c);">
<img
src="{{ image | image_url: width: 300 }}"
srcset="{{ image | image_url: width: 360 }} 360w,
{{ image | image_url: width: 540 }} 540w,
{{ image | image_url: width: 720 }} 720w,
{{ image | image_url: width: 1080 }} 1080w"
sizes="(min-width: 990px) calc(50vw - 100px), (min-width: 750px) calc(50vw - 40px), calc(100vw - 30px)"
loading="lazy"
alt="{{ image.alt | escape }}"
width="{{ image.width }}"
height="{{ image.height }}"
style="position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: cover;"
>
</div>
{%- endif -%}Need a product page layout fix?
Broken storefront grids or media sliders hurt conversion immediately. We fix layout collapses, app collisions, and optimize core storefront load times.