B. Changed how Product Images are displayed
Goal
To show additional images under the Featured or Variant image on the product page, should there be any.
How it decides what to show
-
Look at the selected product. If that product has a list of files (images) added in the metafield: Global Images, it will display these under the Featured image.
-
If the metafield is empty, it displays nothing.
What you create in the Shopify admin
Do these steps once, if not already created
Add metafield definitions for Products
• Settings → Custom data → Products → Add definition
• Name: global_images
• Type: List of Files
• Namespace and key: custom.global_images
Add the content

You will do this in each product that needs additional images. Scroll down to the metafield called Global Images, add each image you want to display inside the metafield and save your work.
Testing checklist
Run these after you add content.
- Product level cards only
• Add images in the metafield
• Expected: the extra images appear
Final fallback
• If there are no images added in the metafield it will seem as if nothing has changed.
For curious minds
• The code uses a newly build snippets/product-gallery-global.liquid and then uses this code in the main-product.liquid file alongside the regular product-gallery.liquid snippet.
Here the code used in the Snippet:
{%- assign global_images = product.metafields.custom.global_images -%}{%- if global_images != blank -%}<div class="product-gallery product-gallery--custom-global-images"><div class="image-slider" style="position: relative; overflow: hidden;"><div class="slider-track" style="display: flex; transition: transform 0.3s ease;">{%- for media_file in global_images.value -%}{%- if media_file.media_type == 'image' -%}<div class="slider-item" style="min-width: 100%; flex-shrink: 0;"><imgsrc="{{ media_file | image_url: width: 589 }}"alt="{{ media_file.alt | escape | default: product.title }}"loading="lazy"class="product-gallery__media-image rounded"style="display: block; width: 100%; aspect-ratio: 1 / 1; object-fit: cover;"/></div>{%- endif -%}{%- endfor -%}</div>
<!-- Navigation Arrows --><button class="slider-prev" style="position: absolute; left: 10px; top: 50%; transform: translateY(-50%); background-color: rgb(0, 0, 0); color: white; border: 0px solid rgba(255, 255, 255, 0.12); padding: 0; cursor: pointer; border-radius: 9999px; z-index: 10; font-size: 24px; font-weight: bold; display: flex; align-items: center; justify-content: center; width: 44.8px; height: 44.8px;">‹</button><button class="slider-next" style="position: absolute; right: 10px; top: 50%; transform: translateY(-50%); background-color: rgb(0, 0, 0); color: white; border: 0px solid rgba(255, 255, 255, 0.12); padding: 0; cursor: pointer; border-radius: 9999px; z-index: 10; font-size: 24px; font-weight: bold; display: flex; align-items: center; justify-content: center; width: 44.8px; height: 44.8px;">›</button>
<!-- Pagination Dots --><div class="slider-dots" style="display: flex; justify-content: center; gap: 8px; margin-top: 16px;"></div></div></div><script>(function() {const track = document.querySelector('.slider-track');const items = document.querySelectorAll('.slider-item');const prevBtn = document.querySelector('.slider-prev');const nextBtn = document.querySelector('.slider-next');const dotsContainer = document.querySelector('.slider-dots');let currentIndex = 0;// Create dotsitems.forEach((_, index) => {const dot = document.createElement('button');dot.style.cssText = 'width: 10px; height: 10px; border-radius: 50%; border: none; cursor: pointer; background: #ccc;';if (index === 0) dot.style.background = '#333';dot.addEventListener('click', () => goToSlide(index));dotsContainer.appendChild(dot);});function updateSlider() {track.style.transform = `translateX(-${currentIndex * 100}%)`;document.querySelectorAll('.slider-dots button').forEach((dot, index) => {dot.style.background = index === currentIndex ? '#333' : '#ccc';});}function goToSlide(index) {currentIndex = index;updateSlider();}prevBtn.addEventListener('click', () => {currentIndex = currentIndex > 0 ? currentIndex - 1 : items.length - 1;updateSlider();});nextBtn.addEventListener('click', () => {currentIndex = currentIndex < items.length - 1 ? currentIndex + 1 : 0;updateSlider();});// Touch supportlet startX = 0;track.addEventListener('touchstart', (e) => startX = e.touches[0].clientX);track.addEventListener('touchend', (e) => {const endX = e.changedTouches[0].clientX;if (startX - endX > 50) nextBtn.click();if (endX - startX > 50) prevBtn.click();});})();</script>{%- endif -%}
Here the code in the main-product.liquid file:
<!-- Code for Global Images --><div {% render 'section-properties', tight: true %}><product-rerenderid="product-info-{{ product.id }}-{{ section.id }}"observe-form="{{ product_form_id }}"allow-partial-rerender><div class="product product--stacked-galleries"><!-- LEFT COLUMN: Both galleries stacked vertically --><div class="product__media-stack">{%- if product.media.size > 0 -%}{%- render 'product-gallery', product: product, product_form_id: product_form_id -%}{%- render 'product-gallery-global', product: product -%}{%- endif -%}</div><!-- RIGHT COLUMN: Product Info --><div class="product__info-stack">{%- render 'product-info',product: product,update_url: true,product_form_id: product_form_id,context: 'main_product'-%}</div></div></product-rerender>{%- render 'recommended-products' -%}</div><style>/* Create 2-column layout: galleries left, info right */.product--stacked-galleries {display: grid !important;grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);gap: 4rem;align-items: start; /* aligns product info to the top */}/* Stack the two galleries vertically */.product__media-stack {display: flex;flex-direction: column;gap: 2rem;justify-content: flex-start;}.product__media-stack .product-gallery {width: 100%;display: block !important;}/* Make sure info column is top aligned */.product__info-stack {align-self: start;}/* Responsive layout for smaller screens */@media (max-width: 999px) {.product--stacked-galleries {grid-template-columns: 1fr;}.product__media-stack {flex-direction: column;}}</style><!-- End Code for Global Images -->