Di 39 Produk Variants dan High-variant Products kita udah nyentuh featured_media varian dan case media_type. Sekarang kita bahas media produk secara utuh: empat tipenya, cara render, galeri, AR, dan aturan UX yang bikin galerinya enak dipakai.

Selain gambar, merchant bisa upload model 3D dan video, dan nempelin video YouTube atau Vimeo sebagai media produk. Ini kesempatan buat pengalaman produk yang kaya dan imersif, tapi tiap tipe punya cara render dan kebutuhan UX yang beda.

Object dan Filter yang Dipakai

  1. product.media, array semua media produk, tiap item object media dengan media_type (image, video, external_video, model), id, alt, position, preview_image. Dibahas di 14 Objects Produk dan Koleksi > media.
  2. Object spesifik: video dan video_source, external_video, model dan model_source.
  3. Filter media dari 19 Filters HTML, URL, Media, Color, dan Font > Filter Media: media_tag, video_tag, external_video_tag, external_video_url, model_viewer_tag, plus image_url/image_tag buat gambar.

Snippet Media yang Bisa Dipakai Ulang

Media produk biasanya tampil di halaman produk, tapi kamu mungkin butuh di tempat lain juga (quick view, kartu produk, featured product). Jadi bangun tampilannya di snippet. Di section produk, loop product.media dan render snippet-nya:

{% for media in product.media %}
  {% render 'media', media: media %}
{% endfor %}

Snippet media.liquid, case per tipe:

{% case media.media_type %}
  {% when 'image' %}
    <div class="product-single__media" style="padding-top: {{ 1 | divided_by: media.aspect_ratio | times: 100 }}%;" data-media-id="{{ media.id }}">
      {{ media | image_url: width: 2048, height: 2048 | image_tag }}
    </div>
  {% when 'external_video' %}
    <div class="product-single__media" style="padding-top: {{ 1 | divided_by: media.aspect_ratio | times: 100 }}%;" data-media-id="{{ media.id }}">
      {{ media | external_video_tag }}
    </div>
  {% when 'video' %}
    <div class="product-single__media" data-media-id="{{ media.id }}">
      {{ media | video_tag: controls: true }}
    </div>
  {% when 'model' %}
    <div class="product-single__media" style="padding-top: 100%;" data-media-id="{{ media.id }}">
      {{ media | model_viewer_tag }}
    </div>
  {% else %}
    <div class="product-single__media" style="padding-top: 100%;" data-media-id="{{ media.id }}">
      {{ media | media_tag }}
    </div>
{% endcase %}

Tiap tipe dibungkus <div> dengan style dan atribut data yang alasannya dijelasin di pertimbangan UX di bawah. Dua hal yang perlu diperhatiin:

  1. data-media-id="{{ media.id }}" di tiap pembungkus, buat nyambungin sama thumbnail dan buat JavaScript ganti media aktif waktu varian berubah.
  2. {% else %} pakai media_tag, filter generik yang ngerender tipe apapun. Cadangan kalau ada tipe baru di masa depan.

Contoh Dawn: sections/main-product.liquid dan snippets/product-thumbnail.liquid.

Pertimbangan UX Dasar

Tiap theme butuh pendekatan sendiri buat media responsif, tapi ada dua hal umum:

1. Media Harus Responsif

  1. Model 3D dirender pakai komponen Google model-viewer, dan video eksternal dirender di <iframe>. Dua-duanya gak responsif bawaannya.
  2. Video Shopify dirender di player HTML5 yang responsif, tapi baru setelah dirender.

Solusinya: aspect ratio box, wadah yang tingginya diatur padding-top sesuai rasio media, biar ruangnya udah ada sebelum medianya dimuat. Buat gambar dan video eksternal pakai media.aspect_ratio, buat model 3D yang gak punya rasio tetap, praktik umumnya wadah persegi (padding-top: 100%). Ini juga nyegah layout shift, dibahas di 62 Performance Mobile dan Layout. Di CSS modern kamu bisa pakai aspect-ratio: {{ media.aspect_ratio }} sebagai pengganti trik padding-top.

2. Interaktivitas Harus Terjaga

Video (Shopify maupun eksternal) punya progress bar dan kontrol volume, model 3D bisa diputar. Kalau media ini ada di carousel atau tampilan swipe, komponen interaktifnya gak boleh bertabrakan sama gestur carousel. Pembeli yang ngegeser progress bar video jangan sampai malah pindah slide.

Dan karena produk bisa punya banyak video, kalau theme kamu nampilin thumbnail atau beberapa media sekaligus, pastiin cuma video yang aktif yang main.

Preview Image

Semua tipe media punya preview_image, gambar statis yang mewakili media itu (frame video, render model 3D, atau gambarnya sendiri). Dan image_url yang diterapin ke object media langsung ngembaliin URL preview_image, jadi {{ media | image_url: width: 300 }} jalan buat tipe apapun.

1. Thumbnail Produk

Kalau theme nampilin thumbnail tiap media, pakai preview_image:

{% if product.media.size > 1 %}
  <div class="thumbnails-wrapper">
    {% for media in product.media %}
      <a data-thumbnail-id="{{ media.id }}">
        {{ media.preview_image | image_url: width: 110, height: 110, scale: 2 | image_tag: media.alt, 'product-single__thumbnail-image' }}
      </a>
    {% endfor %}
  </div>
{% endif %}

data-thumbnail-id dipasangin sama data-media-id di tampilan utama, jadi JavaScript tinggal nyocokin ID buat ganti media yang tampil. Cek product.media.size > 1 biar produk dengan satu gambar gak dapat baris thumbnail yang cuma satu.

2. Gambar Open Graph

Preview media (bukan cuma gambar) bisa dipakai buat preview media sosial:

{%- if template.name == 'product' -%}
  {%- assign og_title = product.title | strip_html -%}
  {%- assign og_type = 'product' -%}
  {%- if product.media.size > 0 -%}
    {%- capture og_image_tags -%}
      {% for media in product.media limit:3 -%}
        <meta property="og:image" content="http:{{ media | image_url: width: 1200 height: 1200 }}" />
      {%- endfor %}
    {%- endcapture -%}
    {%- capture og_image_secure_url_tags -%}
      {% for media in product.media limit:3 -%}
        <meta property="og:image:secure_url" content="https:{{ media | image_url: with: 1200, height: 1200 }}" />
      {%- endfor %}
    {%- endcapture -%}
  {%- endif -%}
{%- endif -%}

Tiga media pertama jadi og:image. Detail meta tag SEO dan sosial di 48 SEO Metadata, hreflang, robots.txt.

AR: View in Your Space

Kalau merchant punya model 3D, kamu bisa nyediain AR lewat library Shopify-XR, yang ndukung AR Quick Look di Safari iOS dan Scene Viewer di Android. Dua langkah:

1. Inisialisasi Library

JavaScript ini harus ada di halaman produk:

<script>
function setupShopifyXr(){
  if (!window.ShopifyXR) {
    document.addEventListener('shopify_xr_initialized', function() {
      setupShopifyXr();
    });
  }else{
    {% assign models = product.media | where: 'media_type', 'model' | json -%}
    window.ShopifyXR.addModels({{ models }});
    window.ShopifyXR.setupXRElements();
  }
}
window.Shopify.loadFeatures([
  {
    name: 'shopify-xr',
    version: '1.0',
    onLoad: setupShopifyXr
  }
]);
</script>

Bedah:

  1. window.Shopify.loadFeatures ngeload library shopify-xr versi 1.0 on demand (gak dimuat di halaman yang gak butuh), terus manggil setupShopifyXr waktu siap.
  2. Kalau window.ShopifyXR belum ada, tunggu event shopify_xr_initialized.
  3. product.media | where: 'media_type', 'model' | json nyaring cuma model 3D dan ngubahnya jadi JSON buat addModels. Filter where dan json dari 18 Filters String, Math, dan Array.
  4. setupXRElements nyari elemen dengan data-shopify-xr di DOM dan masang click handler.

2. Nampilin AR

Lewat tombol, dengan atribut:

  1. data-shopify-xr, penanda buat library masang handler.
  2. data-shopify-model3d-id, ID media model-nya.
  3. data-shopify-title, judul produk.
  4. data-shopify-xr-hidden, atribut dasar yang dirujuk library (tombolnya disembunyiin sampai library mastiin perangkatnya ndukung AR).

Satu tombol per media model:

{% for media in product.media %}
  {% case media.type %}
    ...
    {% when 'model' %}
      <div class="product-single__media" style="padding-top: 100%;" data-media-id="{{ media.id }}">
        {{ media | model_viewer_tag }}
      </div>
      <button
        data-shopify-xr
        data-shopify-model3d-id="{{ media.id }}"
        data-shopify-title="{{ product.title | escape }}"
        data-shopify-xr-hidden
      />
    ...
  {% endcase %}
{% endfor %}

Lewat JavaScript, tanpa tombol:

<script>
  window.ShopifyXR.launchXR({
    model3dId: [media-id],
    title: "{{ product.title | escape }}",
  });
</script>

[media-id] diganti ID media model-nya.

Parameter Video

Video Shopify bisa dikasih semua atribut HTML5 <video> waktu dirender pakai video_tag atau media_tag. Yang umum: autoplay, loop, muted, controls. Semuanya false bawaannya:

<!-- Autoplay a video -->
{{ media | video_tag: autoplay: true }}
<!-- Autoplay a video, and loop it -->
{{ media | video_tag: autoplay: true, loop: true }}
<!-- Autoplay a video, loop it, and mute it -->
{{ media | video_tag: autoplay: true, loop: true, muted: true }}
<!-- Autoplay a video, loop it, mute it, and allow the user to control the video playback -->
{{ media | video_tag: autoplay: true, loop: true, muted: true, controls: true }}

Ingat: browser nolak autoplay dengan suara, jadi autoplay: true harus bareng muted: true kalau mau jalan. Dan pedoman UX di bawah bilang video gak boleh autoplay di load halaman produk, kecuali dibisukan dan itu keputusan desain yang sadar (misalnya video latar hero).

❌ gak bakal autoplay di kebanyakan browser

{{ media | video_tag: autoplay: true }}

✅ bisu, jadi diizinin

{{ media | video_tag: autoplay: true, muted: true, loop: true }}

Buat video eksternal, perilaku yang sama diatur lewat parameter filter external_video_url, tapi parameter yang tersedia tergantung host-nya (YouTube dan Vimeo punya nama parameter beda).

Pedoman UX Media Produk

1. Badge dan Tombol

Tampilan video dan model 3D harus punya:

  1. Badge ikon play (video) atau 3D (model) di thumbnail.
  2. Tombol kontrol play atau 3D di media utama.
  3. Buat model 3D, tombol View in your space.

Ikon: pakai yang dari asset library Shopify, bukan bikin sendiri, karena itu standar industri yang langsung dikenali pembeli. Ada dua gaya, rounded dan angular, pilih satu yang cocok sama theme.

Ukuran badge thumbnail: maksimal 1/9 area thumbnail (1/6 buat thumbnail landscape), minimal 20×20px. Boleh di pojok manapun tapi seragam. Tombol kontrol utama: minimal 60×60px, maksimal 90×90px.

Styling:

  1. Jaga whitespace di sekitar ikon dan proporsinya.
  2. Latar badge dan tombol boleh diubah (lingkaran, sudut membulat) sesuai theme.
  3. Pakai setting warna yang udah ada, dengan kontras tinggi antara latar dan ikon, dan antara media dan latar. Setting “Main background”, “Heading”, atau “Text” biasanya paling pas.
  4. Opasitas badge thumbnail: ikon 60%, latar 100%, border minimal 5% opasitas warna ikon.
  5. Opasitas tombol utama: ikon 100% (dan tetap kelihatan waktu hover), latar minimal 75%, border minimal 5%.

Tombol View in your space:

  1. Kalau ditaruh di atas media, jangan nutupin kontrol video/3D.
  2. Cuma tampil di perangkat yang ndukung AR: iOS 13+ atau Android 9+.
  3. Kalau produk punya model 3D, tombolnya tampil terus apapun media yang lagi aktif. Kalau ada lebih dari satu model, buka yang lagi kelihatan, atau yang pertama.
  4. Pakai ikon 3D, ditaruh di bawah media utama, dan latarnya tanpa warna atau sangat netral biar gak bersaing sama tombol Add to cart.

2. 3D Model Viewer

Aksesibilitas:

  1. Model gak aktif waktu halaman dimuat, karena kalau langsung aktif bisa mengejutkan dan mengganggu.
  2. Bisa dipan pakai keyboard aja, selain mouse dan swipe.
  3. Tombol kontrol khusus dengan label buat ngatur posisi model.
  4. State fokus keyboard kelihatan.
  5. Jangan mindahin fokus waktu tombol kontrol ditekan, biar pembeli bisa pergi kapan mau.
  6. Sediain deskripsi teks model buat tiap tampilan.
  7. Umumin state model lewat ARIA live waktu kontrol dipakai.
  8. Tes dengan berbagai teknologi bantu.

Elemen tampilan: kontrol viewer di pojok kanan bawah (ikon boleh sampai 55% opasitas, sudut gak dibulatin kecuali theme-nya bulat), dan progress bar loading model di atas media dengan 100% opasitas.

Urutan fokus: waktu inaktif, cuma kontrol viewer. Waktu aktif: wadah viewer → zoom in → zoom out → fullscreen.

3. Video Player

  1. Video pause waktu halaman dimuat. Kalau harus main otomatis, bisu.
  2. Kontrol ditaruh di bawah media utama, dengan padding rata atau tanpa padding.
  3. Konsisten sama state fokus theme (kustom atau bawaan browser), dan sudut gak dibulatin kecuali theme-nya bulat.
  4. Tes dengan teknologi bantu.

4. Perilaku Umum

“Aktif” buat video berarti “playing”, “inaktif” berarti “paused”. Waktu pembeli maju di galeri, video dan model yang gak kelihatan harus inaktif. Kalau lebih dari satu media tampil sekaligus, semua inaktif, pembeli yang mulai. Kalau cuma satu yang tampil:

  1. Desktop: media pertama inaktif waktu load, tapi waktu media berganti, media sekarang otomatis aktif.
  2. Tablet/mobile: semua inaktif, pembeli yang mulai.

5. Slideshow

Kalau galeri pakai slideshow, jangan cuma andelin gestur swipe buat navigasi, karena video player dan 3D viewer bisa mengganggu (ngegeser di atas video ngatur volume, bukan pindah slide). Sediain tombol panah dan thumbnail sebagai jalur navigasi alternatif.

Ringkasan

  1. Empat tipe media: image, video (Shopify), external_video (YouTube/Vimeo, <iframe>), model (3D, model-viewer). Loop product.media dan case media.media_type dengan filter yang sesuai, media_tag sebagai cadangan.
  2. Bangun di snippet biar bisa dipakai di luar halaman produk, dengan data-media-id di tiap pembungkus.
  3. Aspect ratio box (padding-top dari aspect_ratio, persegi buat 3D) karena iframe dan model-viewer gak responsif dan buat nyegah layout shift.
  4. Kontrol interaktif jangan bentrok sama carousel, dan cuma video aktif yang main.
  5. preview_image ada di semua tipe, image_url pada media langsung ngembaliin preview-nya, buat thumbnail (data-thumbnail-id) dan og:image.
  6. AR: Shopify.loadFeatures ngeload shopify-xr, addModels dengan product.media | where: 'media_type', 'model' | json, tombol dengan data-shopify-xr, data-shopify-model3d-id, data-shopify-title, data-shopify-xr-hidden, atau launchXR via JavaScript.
  7. Parameter video: autoplay, loop, muted, controls, semua default false, autoplay butuh muted. Video eksternal lewat external_video_url tergantung host.
  8. UX badge: ikon standar Shopify (satu gaya), badge thumbnail ≤ 1/9 area dan ≥ 20px, tombol utama 60–90px, opasitas ikon 60%/100%, latar 100%/≥75%, warna dari setting theme.
  9. View in your space: cuma perangkat AR (iOS 13+/Android 9+), tampil terus kalau ada model, di bawah media, latar netral.
  10. 3D dan video inaktif waktu load, navigasi keyboard, fokus gak dipindah, ARIA live, kontrol di kanan bawah (3D) atau bawah (video), progress bar 3D di atas.
  11. Desktop auto-aktif waktu media berganti, mobile selalu manual, dan slideshow jangan cuma swipe.

Bab selanjutnya kita bahas tiga fitur produk lain: rekomendasi produk (related dan complementary lewat Product Recommendations API dan object recommendations), template gift card beserta QR code dan Apple Wallet, dan bundle di email notifikasi.