Di 13 Objects Global kita kenalan sama object yang ada di mana-mana. Sekarang object yang jadi inti jualan: produk, varian, koleksi, dan gambar-gambarnya.

Ini bab object yang paling gede, karena product itu object paling kaya di Liquid. Tapi gak semua propertinya bakal kamu pakai tiap hari. Yang paling sering: title, price, url, featured_image, variants, selected_or_first_available_variant, dan available.

Soal Harga: Subunit

Sebelum masuk ke object-nya, ada satu konsep yang bakal muncul terus: semua harga di Liquid itu dalam subunit mata uang, alias satuan terkecilnya. Dolar dalam sen, Rupiah dalam… ya Rupiah tetap, tapi dikali 100.

Jadi product.price buat produk seharga $10.00 itu 1000, bukan 10. Buat mata uang tanpa subunit kaya Yen dan Won, tetap ditambahin dua digit: ¥1000 jadi 100000.

Kenapa gini? Karena angka bulat gak punya masalah pembulatan kaya angka desimal. 0.1 + 0.2 di komputer itu 0.30000000000000004, tapi 10 + 20 itu selalu 30. Buat urusan uang, itu penting.

Akibatnya: jangan pernah nampilin harga mentah. Selalu lewat filter uang yang dibahas di 20 Filters Money, Metafield, Cart, Customer, dan Localization.

❌ salah, nampilin 1000 padahal maksudnya $10.00

<span>{{ product.price }}</span>

✅ benar

<span>{{ product.price | money }}</span>

Dan harganya udah dalam mata uang lokal pelanggan (presentment currency), jadi pengunjung dari Jepang lihat harga dalam Yen kalau toko mendukung itu.

product

Satu produk di toko. Tersedia langsung di template product, dan lewat object induk kaya collection.products, cart.items[].product, atau all_products['handle'].

1. Identitas dan Konten

  1. id, ID produk.
  2. title, judul.
  3. handle, handle-nya, buat URL.
  4. url, URL relatif. Di hasil pencarian atau koleksi yang difilter, URL-nya bawa parameter ?variant= dari varian yang paling relevan. Di rekomendasi produk, bawa parameter pelacakan pr_*.
  5. description dan content, deskripsi produk, dua-duanya sama persis (HTML).
  6. vendor, nama vendor/merek.
  7. type, tipe produk (teks bebas yang diisi merchant).
  8. category, kategori dari taksonomi standar Shopify, berupa object taxonomy_category (dibahas di bawah). Beda sama type, ini terstruktur.
  9. tags, array tag, urut abjad.
  10. collections, array koleksi yang berisi produk ini. Koleksi yang gak tersedia di channel Online Store gak diikutkan.
  11. template_suffix, nama alternate template produk ini, tanpa awalan product. dan tanpa ekstensi. nil kalau pakai template default.
  12. created_at dan published_at, timestamp, format pakai filter date.
  13. metafields, metafield produk. Bahasannya di 15 Objects Konten.
  14. gift_card?, true kalau ini gift card.

2. Ketersediaan

available itu true kalau minimal satu varian tersedia. Sebuah varian dianggap tersedia kalau memenuhi salah satu:

  1. variant.inventory_quantity lebih dari 0.
  2. variant.inventory_policy itu continue (tetap jual walau habis).
  3. variant.inventory_management itu nil (stok gak dilacak).
  4. Varian punya delivery profile dengan tarif pengiriman valid.

Jadi produk yang stoknya 0 tapi disetel “tetap jual saat habis” itu tetap available. Ini sering bikin bingung merchant, jadi pahami dulu.

3. Harga

Karena produk punya banyak varian dengan harga beda-beda, product nyediain rentangnya:

  1. price dan price_min, harga terendah di antara semua varian. Dua-duanya sama.
  2. price_max, harga tertinggi.
  3. price_varies, true kalau harga variannya beda-beda.
  4. compare_at_price dan compare_at_price_min, harga coret terendah.
  5. compare_at_price_max, harga coret tertinggi.
  6. compare_at_price_varies, true kalau harga coretnya beda-beda.

Pola umum nampilin “mulai dari”:

{% if product.price_varies %}
  Mulai dari {{ product.price_min | money }}
{% else %}
  {{ product.price | money }}
{% endif %}

4. Gambar dan Media

  1. featured_image, gambar pertama (unggulan), object image.
  2. images, array semua gambar.
  3. featured_media, media pertama, object media. Di hasil pencarian atau koleksi terfilter, yang dikembalikan media dari varian paling relevan.
  4. media, array semua media (gambar, video, model 3D), urut tanggal ditambahin.

Bedanya images sama media: images cuma gambar, media semua jenis. Theme modern pakai media biar bisa nampilin video dan 3D. Bahasannya di 40 Produk Media.

5. Varian

  1. variants, array semua varian. Maksimal 250 kalau gak di-paginate, dan kalau di-paginate maksimal 50 per halaman.
  2. variants_count, jumlah total varian.
  3. has_only_default_variant, true kalau produk gak punya opsi (cuma satu varian bawaan). Ini yang dipakai buat nyembunyiin pemilih varian.
  4. first_available_variant, varian pertama yang tersedia.
  5. selected_variant, varian yang lagi dipilih lewat parameter URL ?variant=. nil kalau gak ada yang dipilih.
  6. selected_or_first_available_variant, ini yang paling sering dipakai: varian yang dipilih kalau ada (gak peduli tersedia atau nggak), kalau nggak ya varian pertama yang tersedia, kalau gak ada yang tersedia ya varian pertama.

Pola standar di form produk:

{% assign current_variant = product.selected_or_first_available_variant %}
{% form 'product', product %}
  <input type="hidden" name="id" value="{{ current_variant.id }}">
  <button {% unless current_variant.available %}disabled{% endunless %}>
    {% if current_variant.available %}Add to cart{% else %}Sold out{% endif %}
  </button>
{% endform %}

6. Opsi

Opsi itu “Size”, “Color”, dan sejenisnya. Nilainya “S”, “M”, “Merah”, dan sebagainya. Kombinasi nilai opsi = satu varian.

  1. options, array nama opsinya aja, misalnya ["Size", "Strength"].
  2. options_with_values, array object product_option yang punya nama dan nilai-nilainya.
  3. options_by_name, akses satu opsi pakai namanya, gak peduli huruf besar-kecil.
{% if product.options.size > 0 -%}
  {% for option in product.options -%}
    - {{ option }}
  {%- endfor %}
{%- endif %}

Hasilnya:

- Size
- Strength

Bikin dropdown buat satu opsi:

<label>
  Strength
  <select>
    {%- for value in product.options_by_name['strength'].values %}
    <option>{{ value }}</option>
    {%- endfor %}
  </select>
</label>

Hasilnya:

<label>
  Strength
  <select>
    <option>Low</option>
    <option>Medium</option>
    <option>High</option>
  </select>
</label>

7. Selling Plan

Buat produk dengan purchase options (langganan, pre-order, try before you buy):

  1. selling_plan_groups, array selling_plan_group yang berisi varian-varian produk ini.
  2. requires_selling_plan, true kalau semua varian wajib pakai selling plan (gak bisa beli sekali).
  3. selected_selling_plan, selling plan yang dipilih lewat parameter URL ?selling_plan=. nil kalau gak ada.
  4. selected_selling_plan_allocation, alokasi selling plan buat varian yang dipilih. nil kalau gak ada varian dan selling plan yang dipilih.
  5. selected_or_first_available_selling_plan_allocation, alokasi yang dipilih, atau alokasi pertama di varian pertama yang tersedia, atau alokasi pertama di varian pertama. nil kalau produknya gak punya selling plan.

Object selling plan dibahas di bawah, cara pakainya di 44 Subscriptions dan 45 Pre-orders dan Try Before You Buy.

8. Lainnya

quantity_price_breaks_configured?, true kalau ada varian dengan harga grosir (B2B) buat pelanggan sekarang.

variant

Satu varian produk. Ini yang beneran dibeli: yang masuk keranjang itu ID varian, bukan ID produk.

1. Identitas

  1. id, ID varian. Ini yang dikirim di <input name="id">.
  2. title, gabungan nilai opsinya dipisah /, misalnya S / Low.
  3. sku, SKU.
  4. barcode, barcode.
  5. product, produk induknya.
  6. url, URL varian dengan format /products/[handle]?variant=[id]. Di hasil pencarian dan koleksi terfilter, bawa parameter pelacakan (_pos, _sid, _ss, _fid).
  7. metafields, metafield varian.

2. Harga

  1. price, harga varian dalam subunit.
  2. compare_at_price, harga coret. nil kalau gak ada.
  3. unit_price, harga per satuan (misalnya per 100ml), buat aturan unit pricing di beberapa negara.
  4. unit_price_measurement, satuan ukurannya, object unit_price_measurement.
  5. quantity_price_breaks, array quantity_price_break buat harga grosir B2B.
  6. quantity_price_breaks_configured?, true kalau ada harga grosir.
  7. quantity_rule, aturan jumlah pembelian (min, max, increment). Bawaannya min=1, max=null, increment=1. Diatur di katalog B2B.
  8. taxable, true kalau kena pajak.

3. Stok

  1. available, true kalau tersedia (aturan sama kaya di product.available).
  2. inventory_quantity, jumlah stok. Kalau stok gak dilacak, yang dikembalikan malah jumlah yang terjual. Jadi cek inventory_management dulu.
  3. inventory_management, layanan pelacak stok. nil kalau gak dilacak.
  4. inventory_policy, continue (tetap jual saat habis) atau deny (berhenti jual).
  5. incoming, true kalau ada stok yang lagi dalam perjalanan.
  6. next_incoming_date, tanggal kedatangan stok berikutnya.
  7. requires_shipping, true kalau butuh pengiriman.
  8. store_availabilities, array store_availability buat fitur ambil di toko. Cuma terisi kalau variant.selected itu true atau varian ini varian pertama yang tersedia. Bahasannya di 49 Delivery Pickup Availability.

❌ salah, inventory_quantity gak bermakna kalau stok gak dilacak

Stok: {{ variant.inventory_quantity }}

✅ benar, cek dulu apakah dilacak

{% if variant.inventory_management != nil %}
  Stok: {{ variant.inventory_quantity }}
{% endif %}

4. Opsi dan Pilihan

  1. options, array nilai opsi varian ini, misalnya ["S", "Low"]. Ini pengganti option1, option2, option3 yang udah deprecated.
  2. options_with_values, array option_with_value berisi pasangan name dan value. Gak pernah kosong, karena varian tanpa opsi tetap punya opsi default. Cek product.has_only_default_variant sebelum loop.
  3. selected, true kalau varian ini yang dipilih lewat parameter URL ?variant=. Cuma berlaku di halaman produk.
  4. matched, true kalau varian ini cocok sama filter storefront yang aktif, atau gak ada filter.

Contoh nampilin ID dan opsi tiap varian:

{% for variant in product.variants -%}
  {%- capture options -%}
    {% for option in variant.options -%}
      {{ option }}{%- unless forloop.last -%}/{%- endunless -%}
    {%- endfor %}
  {%- endcapture -%}
  {{ variant.id }}: {{ options }}
{%- endfor %}

Hasilnya:

39897499729985: S/Low
39897499762753: S/Medium
39897499795521: S/High

❌ deprecated

{{ variant.option1 }} / {{ variant.option2 }}

✅ benar

{{ variant.options | join: ' / ' }}

5. Gambar

  1. image dan featured_image, gambar varian, dua-duanya sama. nil kalau varian gak punya gambar sendiri.
  2. featured_media, media pertama varian.

6. Berat

  1. weight, berat dalam gram, selalu.
  2. weight_in_unit, berat dalam satuan yang diatur di varian.
  3. weight_unit, satuannya (g, kg, lb, oz).

Buat nampilin, pakai filter weight_with_unit dengan weight_in_unit dan weight_unit.

7. Selling Plan

  1. requires_selling_plan, true kalau varian wajib pakai selling plan.
  2. selling_plan_allocations, array semua alokasi selling plan varian ini.
  3. selected_selling_plan_allocation, alokasi yang dipilih lewat parameter URL ?selling_plan=.

Object Opsi

1. product_option

Satu opsi produk (misalnya “Size”):

  1. name, nama opsi.
  2. position, urutan opsi, mulai dari 1.
  3. values, array product_option_value.
  4. selected_value, nilai yang lagi dipilih. Kalau gak ada, nilai dari varian pertama yang tersedia.

2. product_option_value

Satu nilai opsi (misalnya “Merah” buat opsi “Color”):

  1. name, nama nilainya.
  2. id, ID-nya.
  3. selected, true kalau lagi dipilih.
  4. available, apakah nilai ini punya kombinasi yang bisa dibeli dalam konteks opsi-opsi sebelumnya yang udah dipilih. Contoh produk Color/Size/Material dengan Red/Small/Cotton dipilih: available di Color ngecek apakah ada varian Red yang tersedia, di Size ngecek apakah ada Red+Small yang tersedia, di Material ngecek Red+Small+Cotton.
  5. variant, varian yang cocok dengan nilai ini digabung nilai opsi lain yang lagi dipilih. Ini cara yang disarankan buat nampilin ketersediaan nilai opsi, dibahas di 39 Produk Variants dan High-variant Products.
  6. swatch, object swatch buat tampilan visual. nil kalau gak ada warna atau gambar yang disimpan.
  7. product_url, URL kalau nilai ini terkait produk lain (buat combined listings). nil kalau nggak.

3. option_with_value

Pasangan opsi dan nilai buat satu varian: name dan value (object product_option_value). Dikembalikan oleh variant.options_with_values dan line_item.options_with_values.

4. swatch

Representasi visual nilai opsi atau nilai filter: color (object color) dan image (object image). Ini yang bikin pemilih warna bisa nampilin kotak warna beneran, bukan cuma teks “Merah”.

collection

Satu koleksi di toko. Tersedia di template collection, dan lewat collections['handle'] atau product.collections.

1. Identitas dan Konten

  1. id, title, handle, url, description.
  2. image dan featured_image, gambar koleksi.
  3. published_at, timestamp.
  4. template_suffix, alternate template-nya.
  5. metafields.

2. Produk

  1. products, array produk di koleksi. Bisa di-paginate, dan ingat aturan 11 Tags Perulangan > paginate: tanpa paginate, cuma 50 produk pertama yang diambil.
  2. products_count, jumlah produk di tampilan sekarang (setelah filter).
  3. all_products_count, jumlah produk total, termasuk yang kefilter.
  4. next_product dan previous_product, produk berikutnya dan sebelumnya di koleksi, buat navigasi “produk selanjutnya” di halaman produk. nil kalau gak ada.

3. Tag, Tipe, Vendor

  1. all_tags, semua tag produk di koleksi, termasuk yang kefilter. Maksimal 1.000 tag.
  2. tags, tag yang lagi aktif sebagai filter.
  3. all_types, semua tipe produk di koleksi.
  4. all_vendors, semua vendor di koleksi.
  5. current_type, tipe produk di halaman koleksi-per-tipe (/collections/types?q=...).
  6. current_vendor, vendor di halaman koleksi-per-vendor.
{% for product_type in collection.all_types -%}
  {{- product_type | link_to_type }}
{%- endfor %}

4. Filter dan Urutan

  1. filters, array object filter buat storefront filtering. Dibahas di 17 Objects Lainnya dan 37 Filtering.
  2. sort_by, urutan yang lagi aktif dari parameter URL ?sort_by=.
  3. default_sort_by, urutan default koleksi.
  4. sort_options, array sort_option yang punya name (buat ditampilin) dan value (buat parameter URL).

Pola dropdown urutan:

<select name="sort_by">
  {% for option in collection.sort_options %}
    <option value="{{ option.value }}" {% if option.value == collection.sort_by %}selected{% endif %}>
      {{ option.name }}
    </option>
  {% endfor %}
</select>

image

Satu gambar. Muncul di product.images, product.featured_image, variant.image, collection.image, article.image, dan banyak lagi.

  1. src, URL relatif gambar. Tapi jangan dipakai langsung, pakai filter image_url biar dapat ukuran yang pas dari CDN. Bahasannya di 19 Filters HTML, URL, Media, Color, dan Font.
  2. alt, teks alternatif.
  3. width dan height, ukuran dalam piksel.
  4. aspect_ratio, rasio lebar/tinggi sebagai desimal. Berguna buat ngasih ruang sebelum gambar dimuat (mencegah layout shift).
  5. id, ID gambar.
  6. position, urutan di product.images atau product.media.
  7. product_id, ID produk pemiliknya.
  8. variants, array varian yang pakai gambar ini.
  9. attached_to_variant?, true kalau gambar terkait varian.
  10. media_type, selalu image.
  11. preview_image, gambar preview (buat gambar ya dirinya sendiri, biar konsisten sama media lain).
  12. presentation, object image_presentation yang punya focal_point dengan x dan y dalam persen (bawaan 50/50). Ini titik fokus yang diatur merchant, buat object-position CSS biar bagian penting gambar gak kepotong.

❌ salah, gambar ukuran asli yang bisa 5MB

<img src="{{ product.featured_image.src }}">

✅ benar, minta ukuran yang pas dari CDN

{{ product.featured_image | image_url: width: 600 | image_tag }}

media

Object umum buat semua jenis media di product.media. Propertinya yang dijamin ada di semua jenis:

  1. id.
  2. media_type, jenisnya: image, video, external_video, model, atau generic_file.
  3. alt.
  4. position, urutan di product.media.
  5. preview_image, gambar preview, object image. Ini yang bikin kamu bisa nampilin thumbnail buat video dan model 3D.

Pola dasarnya: loop product.media, cek media_type, terus render sesuai jenisnya:

{% for media in product.media %}
  {% case media.media_type %}
    {% when 'image' %}
      {{ media | image_url: width: 800 | image_tag }}
    {% when 'video' %}
      {{ media | video_tag: controls: true }}
    {% when 'external_video' %}
      {{ media | external_video_tag }}
    {% when 'model' %}
      {{ media | model_viewer_tag }}
  {% endcase %}
{% endfor %}

Filter-filter media itu dibahas di 19 Filters HTML, URL, Media, Color, dan Font, dan cara lengkapnya di 40 Produk Media.

1. video

Video yang di-upload ke Shopify. Selain properti media, punya:

  1. duration, durasi dalam milidetik.
  2. aspect_ratio.
  3. sources, array video_source, tiap-tiapnya punya url (CDN), format, mime_type, width, dan height. Shopify nyediain beberapa resolusi.

2. external_video

Video dari YouTube atau Vimeo:

  1. host, layanan pengehost (youtube atau vimeo).
  2. external_id, ID video di layanan itu.
  3. aspect_ratio.

3. model

Model 3D:

  1. sources, array model_source dengan url, format (misalnya glb, usdz), dan mime_type.

4. generic_file

File umum lainnya: punya url ke CDN.

taxonomy_category

Kategori dari taksonomi produk standar Shopify (beda sama product.type yang teks bebas):

  1. name, nama kategori yang udah dilokalisasi.
  2. id, ID node publik.
  3. gid, ID dalam format Shopify GID.
  4. ancestors, array semua kategori induk sampai ke akar. Buat bikin breadcrumb kategori.

Object B2B dan Unit Pricing

1. quantity_price_break

Harga grosir: minimum_quantity (jumlah minimal) dan price (harga setelah jumlah itu terpenuhi). Bahasannya di 42 Harga Diskon, Currency, Unit Pricing, Installments, B2B.

2. quantity_rule

Aturan jumlah: min, max, increment.

3. unit_price_measurement

Satuan buat unit pricing:

  1. measured_type, jenis ukuran (volume, berat, dan sebagainya).
  2. quantity_value dan quantity_unit, jumlah dan satuan produk (misalnya 500 ml).
  3. reference_value dan reference_unit, jumlah dan satuan acuan harga (misalnya 100 ml).

Object Ambil di Toko

1. store_availability

Ketersediaan varian di satu lokasi:

  1. available, true kalau ada stok di lokasi itu.
  2. location, object location.
  3. pick_up_enabled, true kalau lokasi itu nyalain ambil di toko.
  4. pick_up_time, estimasi waktu siap, misalnya “Usually ready in 24 hours”.

2. location

Satu lokasi toko: name, id, address (object address), latitude, longitude, dan metafields.

Object Selling Plan

Selling plan itu “cara beli” selain beli sekali: langganan mingguan, pre-order, bayar di muka setahun. Strukturnya bertingkat: group → plan → allocation.

1. selling_plan_group

Sekelompok selling plan, biasanya dari satu app:

  1. id, name, app_id.
  2. selling_plans, array selling_plan di grup ini.
  3. options, array selling_plan_group_option (misalnya “Delivery every” dengan nilai “1 week”, “2 weeks”).
  4. selling_plan_selected, true kalau selling plan yang dipilih ada di grup ini.

2. selling_plan_group_option

Satu opsi grup: name, position, values (array string), dan selected_value.

3. selling_plan

Satu rencana:

  1. id, name, description, group_id.
  2. options, array selling_plan_option (name, position, value).
  3. price_adjustments, array selling_plan_price_adjustment: value, value_type, order_count (berlaku buat berapa order), position.
  4. checkout_charge, object selling_plan_checkout_charge (value dan value_type), berapa yang dibayar saat checkout.
  5. recurring_deliveries, true kalau ada pengiriman berulang.
  6. selected, true kalau lagi dipilih.

4. selling_plan_allocation

Selling plan yang udah diterapin ke satu varian, jadi harganya udah konkret:

  1. price, harga alokasi dalam subunit.
  2. compare_at_price, harga coretnya.
  3. per_delivery_price, harga per pengiriman.
  4. checkout_charge_amount, yang dibayar saat checkout.
  5. remaining_balance_charge_amount, sisa yang harus dibayar.
  6. unit_price, harga per satuan.
  7. selling_plan, rencana yang bikin alokasi ini.
  8. selling_plan_group_id.
  9. price_adjustments, array selling_plan_allocation_price_adjustment (price dan position).

Jadi buat nampilin harga langganan yang benar, kamu baca dari allocation, bukan dari variant.price.

recommendations

Rekomendasi produk berdasarkan data penjualan, deskripsi, dan hubungan koleksi. Makin lama makin akurat.

Object ini cuma ngasih produk kalau dirender di section lewat Product Recommendations API dan Section Rendering API. Kalau dipanggil biasa, kosong.

  1. performed?, true kalau lagi dirender lewat API itu.
  2. products, array produk rekomendasi.
  3. products_count, jumlahnya. 0 kalau performed? false.
  4. intent, jenis rekomendasi (related atau complementary). nil kalau performed? false.

Cara pakainya di 41 Produk Recommendations, Gift Card, dan Bundles.

Object Remote

Buat fitur di mana produk toko lain tampil di toko ini:

  1. remote_product, produk dari toko lain, propertinya sama persis kaya product plus remote_details.
  2. remote_details, punya shop (object remote_shop) dan type (sekarang cuma seller).
  3. remote_shop, info toko asal: name, brand, policies, refund_policy, shipping_policy.

Ini kepakai di template product/seller yang dibahas di 24 Template per Halaman.

Ringkasan

  1. Semua harga dalam subunit ($10.00 = 1000), selalu tampilin lewat filter money.
  2. product.available itu true kalau minimal satu varian tersedia, dan varian dianggap tersedia walau stoknya 0 kalau inventory_policy-nya continue.
  3. product.price = price_min, pakai price_varies buat tau harus nampilin “mulai dari” atau nggak.
  4. selected_or_first_available_variant itu varian yang dipakai di form produk, dan yang dikirim ke keranjang itu ID varian.
  5. has_only_default_variant buat nyembunyiin pemilih varian kalau produknya gak punya opsi.
  6. options (nama) vs options_with_values (nama + nilai) vs options_by_name['nama'] (akses satu opsi, gak peduli kapital).
  7. variant.inventory_quantity cuma bermakna kalau inventory_management bukan nil.
  8. variant.option1/2/3 deprecated, pakai variant.options.
  9. product_option_value.variant itu cara yang disarankan buat nampilin ketersediaan tiap nilai opsi.
  10. collection.products butuh paginate buat lebih dari 50, dan products_count (setelah filter) beda sama all_products_count (total).
  11. image.src jangan dipakai langsung, selalu lewat image_url. Pakai aspect_ratio buat mencegah layout shift dan presentation.focal_point buat object-position.
  12. media itu payung buat image, video, external_video, model, dan generic_file, bedain pakai media_type, dan semuanya punya preview_image.
  13. Selling plan bertingkat: group → plan → allocation, dan harga langganan yang benar dibaca dari allocation.
  14. recommendations cuma terisi kalau dirender lewat Product Recommendations API.

Bab selanjutnya kita ke object konten: artikel dan blog beserta komentarnya, halaman, menu dan link buat navigasi, metafield, dan metaobject buat data kustom.