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
id, ID produk.title, judul.handle, handle-nya, buat URL.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 pelacakanpr_*.descriptiondancontent, deskripsi produk, dua-duanya sama persis (HTML).vendor, nama vendor/merek.type, tipe produk (teks bebas yang diisi merchant).category, kategori dari taksonomi standar Shopify, berupa objecttaxonomy_category(dibahas di bawah). Beda samatype, ini terstruktur.tags, array tag, urut abjad.collections, array koleksi yang berisi produk ini. Koleksi yang gak tersedia di channel Online Store gak diikutkan.template_suffix, nama alternate template produk ini, tanpa awalanproduct.dan tanpa ekstensi.nilkalau pakai template default.created_atdanpublished_at, timestamp, format pakai filterdate.metafields, metafield produk. Bahasannya di 15 Objects Konten.gift_card?,truekalau ini gift card.
2. Ketersediaan
available itu true kalau minimal satu varian tersedia. Sebuah varian dianggap tersedia kalau memenuhi salah satu:
variant.inventory_quantitylebih dari 0.variant.inventory_policyitucontinue(tetap jual walau habis).variant.inventory_managementitunil(stok gak dilacak).- 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:
pricedanprice_min, harga terendah di antara semua varian. Dua-duanya sama.price_max, harga tertinggi.price_varies,truekalau harga variannya beda-beda.compare_at_pricedancompare_at_price_min, harga coret terendah.compare_at_price_max, harga coret tertinggi.compare_at_price_varies,truekalau 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
featured_image, gambar pertama (unggulan), objectimage.images, array semua gambar.featured_media, media pertama, objectmedia. Di hasil pencarian atau koleksi terfilter, yang dikembalikan media dari varian paling relevan.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
variants, array semua varian. Maksimal 250 kalau gak di-paginate, dan kalau di-paginate maksimal 50 per halaman.variants_count, jumlah total varian.has_only_default_variant,truekalau produk gak punya opsi (cuma satu varian bawaan). Ini yang dipakai buat nyembunyiin pemilih varian.first_available_variant, varian pertama yang tersedia.selected_variant, varian yang lagi dipilih lewat parameter URL?variant=.nilkalau gak ada yang dipilih.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.
options, array nama opsinya aja, misalnya["Size", "Strength"].options_with_values, array objectproduct_optionyang punya nama dan nilai-nilainya.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
- StrengthBikin 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):
selling_plan_groups, arrayselling_plan_groupyang berisi varian-varian produk ini.requires_selling_plan,truekalau semua varian wajib pakai selling plan (gak bisa beli sekali).selected_selling_plan, selling plan yang dipilih lewat parameter URL?selling_plan=.nilkalau gak ada.selected_selling_plan_allocation, alokasi selling plan buat varian yang dipilih.nilkalau gak ada varian dan selling plan yang dipilih.selected_or_first_available_selling_plan_allocation, alokasi yang dipilih, atau alokasi pertama di varian pertama yang tersedia, atau alokasi pertama di varian pertama.nilkalau 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
id, ID varian. Ini yang dikirim di<input name="id">.title, gabungan nilai opsinya dipisah/, misalnyaS / Low.sku, SKU.barcode, barcode.product, produk induknya.url, URL varian dengan format/products/[handle]?variant=[id]. Di hasil pencarian dan koleksi terfilter, bawa parameter pelacakan (_pos,_sid,_ss,_fid).metafields, metafield varian.
2. Harga
price, harga varian dalam subunit.compare_at_price, harga coret.nilkalau gak ada.unit_price, harga per satuan (misalnya per 100ml), buat aturan unit pricing di beberapa negara.unit_price_measurement, satuan ukurannya, objectunit_price_measurement.quantity_price_breaks, arrayquantity_price_breakbuat harga grosir B2B.quantity_price_breaks_configured?,truekalau ada harga grosir.quantity_rule, aturan jumlah pembelian (min,max,increment). Bawaannyamin=1, max=null, increment=1. Diatur di katalog B2B.taxable,truekalau kena pajak.
3. Stok
available,truekalau tersedia (aturan sama kaya diproduct.available).inventory_quantity, jumlah stok. Kalau stok gak dilacak, yang dikembalikan malah jumlah yang terjual. Jadi cekinventory_managementdulu.inventory_management, layanan pelacak stok.nilkalau gak dilacak.inventory_policy,continue(tetap jual saat habis) ataudeny(berhenti jual).incoming,truekalau ada stok yang lagi dalam perjalanan.next_incoming_date, tanggal kedatangan stok berikutnya.requires_shipping,truekalau butuh pengiriman.store_availabilities, arraystore_availabilitybuat fitur ambil di toko. Cuma terisi kalauvariant.selecteditutrueatau 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
options, array nilai opsi varian ini, misalnya["S", "Low"]. Ini penggantioption1,option2,option3yang udah deprecated.options_with_values, arrayoption_with_valueberisi pasangannamedanvalue. Gak pernah kosong, karena varian tanpa opsi tetap punya opsi default. Cekproduct.has_only_default_variantsebelum loop.selected,truekalau varian ini yang dipilih lewat parameter URL?variant=. Cuma berlaku di halaman produk.matched,truekalau 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
imagedanfeatured_image, gambar varian, dua-duanya sama.nilkalau varian gak punya gambar sendiri.featured_media, media pertama varian.
6. Berat
weight, berat dalam gram, selalu.weight_in_unit, berat dalam satuan yang diatur di varian.weight_unit, satuannya (g,kg,lb,oz).
Buat nampilin, pakai filter weight_with_unit dengan weight_in_unit dan weight_unit.
7. Selling Plan
requires_selling_plan,truekalau varian wajib pakai selling plan.selling_plan_allocations, array semua alokasi selling plan varian ini.selected_selling_plan_allocation, alokasi yang dipilih lewat parameter URL?selling_plan=.
Object Opsi
1. product_option
Satu opsi produk (misalnya “Size”):
name, nama opsi.position, urutan opsi, mulai dari 1.values, arrayproduct_option_value.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”):
name, nama nilainya.id, ID-nya.selected,truekalau lagi dipilih.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:availabledi Color ngecek apakah ada varian Red yang tersedia, di Size ngecek apakah ada Red+Small yang tersedia, di Material ngecek Red+Small+Cotton.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.swatch, objectswatchbuat tampilan visual.nilkalau gak ada warna atau gambar yang disimpan.product_url, URL kalau nilai ini terkait produk lain (buat combined listings).nilkalau 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
id,title,handle,url,description.imagedanfeatured_image, gambar koleksi.published_at, timestamp.template_suffix, alternate template-nya.metafields.
2. Produk
products, array produk di koleksi. Bisa di-paginate, dan ingat aturan 11 Tags Perulangan > paginate: tanpapaginate, cuma 50 produk pertama yang diambil.products_count, jumlah produk di tampilan sekarang (setelah filter).all_products_count, jumlah produk total, termasuk yang kefilter.next_productdanprevious_product, produk berikutnya dan sebelumnya di koleksi, buat navigasi “produk selanjutnya” di halaman produk.nilkalau gak ada.
3. Tag, Tipe, Vendor
all_tags, semua tag produk di koleksi, termasuk yang kefilter. Maksimal 1.000 tag.tags, tag yang lagi aktif sebagai filter.all_types, semua tipe produk di koleksi.all_vendors, semua vendor di koleksi.current_type, tipe produk di halaman koleksi-per-tipe (/collections/types?q=...).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
filters, array objectfilterbuat storefront filtering. Dibahas di 17 Objects Lainnya dan 37 Filtering.sort_by, urutan yang lagi aktif dari parameter URL?sort_by=.default_sort_by, urutan default koleksi.sort_options, arraysort_optionyang punyaname(buat ditampilin) danvalue(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.
src, URL relatif gambar. Tapi jangan dipakai langsung, pakai filterimage_urlbiar dapat ukuran yang pas dari CDN. Bahasannya di 19 Filters HTML, URL, Media, Color, dan Font.alt, teks alternatif.widthdanheight, ukuran dalam piksel.aspect_ratio, rasio lebar/tinggi sebagai desimal. Berguna buat ngasih ruang sebelum gambar dimuat (mencegah layout shift).id, ID gambar.position, urutan diproduct.imagesatauproduct.media.product_id, ID produk pemiliknya.variants, array varian yang pakai gambar ini.attached_to_variant?,truekalau gambar terkait varian.media_type, selaluimage.preview_image, gambar preview (buat gambar ya dirinya sendiri, biar konsisten sama media lain).presentation, objectimage_presentationyang punyafocal_pointdenganxdanydalam persen (bawaan 50/50). Ini titik fokus yang diatur merchant, buatobject-positionCSS 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:
id.media_type, jenisnya:image,video,external_video,model, ataugeneric_file.alt.position, urutan diproduct.media.preview_image, gambar preview, objectimage. 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:
duration, durasi dalam milidetik.aspect_ratio.sources, arrayvideo_source, tiap-tiapnya punyaurl(CDN),format,mime_type,width, danheight. Shopify nyediain beberapa resolusi.
2. external_video
Video dari YouTube atau Vimeo:
host, layanan pengehost (youtubeatauvimeo).external_id, ID video di layanan itu.aspect_ratio.
3. model
Model 3D:
sources, arraymodel_sourcedenganurl,format(misalnyaglb,usdz), danmime_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):
name, nama kategori yang udah dilokalisasi.id, ID node publik.gid, ID dalam format Shopify GID.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:
measured_type, jenis ukuran (volume, berat, dan sebagainya).quantity_valuedanquantity_unit, jumlah dan satuan produk (misalnya500ml).reference_valuedanreference_unit, jumlah dan satuan acuan harga (misalnya100ml).
Object Ambil di Toko
1. store_availability
Ketersediaan varian di satu lokasi:
available,truekalau ada stok di lokasi itu.location, objectlocation.pick_up_enabled,truekalau lokasi itu nyalain ambil di toko.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:
id,name,app_id.selling_plans, arrayselling_plandi grup ini.options, arrayselling_plan_group_option(misalnya “Delivery every” dengan nilai “1 week”, “2 weeks”).selling_plan_selected,truekalau 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:
id,name,description,group_id.options, arrayselling_plan_option(name,position,value).price_adjustments, arrayselling_plan_price_adjustment:value,value_type,order_count(berlaku buat berapa order),position.checkout_charge, objectselling_plan_checkout_charge(valuedanvalue_type), berapa yang dibayar saat checkout.recurring_deliveries,truekalau ada pengiriman berulang.selected,truekalau lagi dipilih.
4. selling_plan_allocation
Selling plan yang udah diterapin ke satu varian, jadi harganya udah konkret:
price, harga alokasi dalam subunit.compare_at_price, harga coretnya.per_delivery_price, harga per pengiriman.checkout_charge_amount, yang dibayar saat checkout.remaining_balance_charge_amount, sisa yang harus dibayar.unit_price, harga per satuan.selling_plan, rencana yang bikin alokasi ini.selling_plan_group_id.price_adjustments, arrayselling_plan_allocation_price_adjustment(pricedanposition).
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.
performed?,truekalau lagi dirender lewat API itu.products, array produk rekomendasi.products_count, jumlahnya.0kalauperformed?false.intent, jenis rekomendasi (relatedataucomplementary).nilkalauperformed?false.
Cara pakainya di 41 Produk Recommendations, Gift Card, dan Bundles.
Object Remote
Buat fitur di mana produk toko lain tampil di toko ini:
remote_product, produk dari toko lain, propertinya sama persis kayaproductplusremote_details.remote_details, punyashop(objectremote_shop) dantype(sekarang cumaseller).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
- Semua harga dalam subunit ($10.00 =
1000), selalu tampilin lewat filtermoney. product.availableitutruekalau minimal satu varian tersedia, dan varian dianggap tersedia walau stoknya 0 kalauinventory_policy-nyacontinue.product.price=price_min, pakaiprice_variesbuat tau harus nampilin “mulai dari” atau nggak.selected_or_first_available_variantitu varian yang dipakai di form produk, dan yang dikirim ke keranjang itu ID varian.has_only_default_variantbuat nyembunyiin pemilih varian kalau produknya gak punya opsi.options(nama) vsoptions_with_values(nama + nilai) vsoptions_by_name['nama'](akses satu opsi, gak peduli kapital).variant.inventory_quantitycuma bermakna kalauinventory_managementbukannil.variant.option1/2/3deprecated, pakaivariant.options.product_option_value.variantitu cara yang disarankan buat nampilin ketersediaan tiap nilai opsi.collection.productsbutuhpaginatebuat lebih dari 50, danproducts_count(setelah filter) beda samaall_products_count(total).image.srcjangan dipakai langsung, selalu lewatimage_url. Pakaiaspect_ratiobuat mencegah layout shift danpresentation.focal_pointbuatobject-position.mediaitu payung buatimage,video,external_video,model, dangeneric_file, bedain pakaimedia_type, dan semuanya punyapreview_image.- Selling plan bertingkat: group → plan → allocation, dan harga langganan yang benar dibaca dari allocation.
recommendationscuma 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.