Dari 26 Sections dan Section Schema sampai 29 Theme Blocks Mendalam kita terus nulis "settings": [...] di schema tanpa bahas isinya secara serius. Sekarang giliran bahan bakunya: setting, semua tipe inputnya, dan apa yang mereka kembalikan ke Liquid.

Setting itu cara kamu ngasih kendali ke merchant tanpa nyentuh kode. Kamu definisiin setting-nya di JSON, theme editor ngerender input-nya, merchant ngisi, dan kamu baca nilainya di Liquid. Makin banyak setting yang tepat, theme kamu makin bisa nyesuain sama brand merchant dan makin fleksibel buat berbagai kasus.

Setting bisa ada di tiga level: theme, section, dan block. Bisa tetap (elemen informasi kaya heading) atau interaktif (dropdown, color picker). Nilainya bisa statis (diketik merchant) atau dari dynamic source (nyambung ke metafield, dibahas di 31 Dynamic Sources dan Fonts).

Dua Kategori

  1. Input settings, bisa nyimpen nilai dan bisa diatur merchant. Ini yang paling banyak: checkbox, text, color, product, dan seterusnya.
  2. Sidebar settings, gak nyimpen nilai dan gak bisa diatur. Cuma elemen informasi (header, paragraph) buat ngerapiin dan ngasih konteks ke input setting.

Lokasi

Setting didefinisiin di dua tempat:

└── theme
  ├── config
  |   ├── settings_schema.json
  |   ...
  ├── sections
  |   ├── main_product.liquid
  |   ├── another_section_file.liquid
  |   ...
  ...
  1. config/settings_schema.json, ngatur isi area Theme settings di theme editor. Setting di sini jadi setting global theme, diakses lewat object settings dari 13 Objects Global > settings. Detail file-nya di 32 Config settings_schema.json, settings_data.json, markets.json.
  2. Tag {% schema %} di section (dan di theme block), buat setting section dan setting block, diakses lewat section.settings dan block.settings.

Bentuk Schema-nya

Setting selalu berupa atribut settings berisi array yang nempel ke object pemiliknya. Contoh dasar yang nyampur sidebar setting, input setting, dan setting bersyarat:

{
  ...
  "settings": [
    {
      "type": "header",
      "content": "My settings"
    },
    {
      "type": "text",
      "id": "my_id",
      "label": "My setting label",
      "default": "Enter text here"
    },
    {
      "type": "select",
      "id": "layout_style",
      "label": "type",
      "options": [
        {
          "value": "flex",
          "label": "Stack"
        },
        {
          "value": "grid",
          "label": "Grid"
        }
      ],
      "default": "flex"
    },
    {
      "type": "select",
      "id": "content_direction",
      "label": "Direction",
      "options": [
        { "value": "row", "label": "Horizontal" },
        { "value": "column", "label": "Vertical" }
      ],
      "default": "column",
      "visible_if": "{{ block.settings.layout_style == 'flex' }}"
    }
  ],
  ...
}

Setting terakhir (content_direction) cuma muncul kalau layout_style bernilai flex, lewat atribut visible_if. Kita bahas di bawah.

Cara Akses Nilainya

Tergantung di mana setting-nya dibikin, aksesnya lewat object yang beda. Kalau setting ini ada di ketiga level:

{
  "type": "text",
  "id": "message",
  "label": "Message",
  "default": "Hello!"
}

Maka aksesnya id ditempel ke object pemiliknya:

// Settings
Message: {{ settings.message }}
// Section
Message: {{ section.settings.message }}
// Block
Message: {{ block.settings.message }}

Hasilnya ketiganya Message: Hello!. Catatan: object settings global juga bisa diakses di aset Liquid (assets/theme.css.liquid misalnya), jadi kamu bisa nulis {{ settings.heading_font }} di CSS.

1. Selalu Cek Formatnya

Setting yang gak punya default otomatis bisa berakhir kosong, yang di Liquid jadi string kosong. Jadi cek dulu sebelum dipakai:

{% unless settings.message == blank %}
  {{ settings.message }}
{% endunless %}

2. Setting Berbasis Sumber Daya

Buat setting yang nunjuk ke sumber daya (page, product, collection, dan seterusnya), ada tiga kemungkinan kosong: gak ada yang dipilih, yang dipilih udah dihapus, atau yang dipilih disembunyiin. Cek pakai blank:

{% if settings.page != blank %}
  {{ settings.page.title }}
  {{ settings.page.content }}
{% else %}
  No page, or invalid page, selected.
{% endif %}

3. Cara Lama (Legacy)

Dulu setting sumber daya cuma ngembaliin handle, bukan object-nya. Kamu harus ambil object-nya sendiri:

{% unless settings.product == blank %}
  {% assign product = all_products[settings.product] %}
  {% if product %}
    {{ product.title }} - {{ product.price }}
  {% else %}
    No product, or invalid product, selected.
  {% endif %}
{% endunless %}

Sekarang setting-nya langsung ngembaliin object. Tapi demi kompatibilitas, kalau kamu output setting-nya langsung ({{ settings.product }}), yang keluar tetap handle-nya. Jadi kode lama gak rusak, dan kode baru bisa langsung settings.product.title.

❌ cara lama, masih jalan tapi gak perlu

{% assign product = all_products[section.settings.product] %}
{{ product.title }}

✅ cara sekarang

{{ section.settings.product.title }}

Setting Bersyarat: visible_if

Setting bisa ditampilin cuma kalau kondisi tertentu terpenuhi, pakai ekspresi boolean di visible_if:

"visible_if": "{{ block.settings.layout_style == 'flex' }}"

Contoh nyata: setting “Direction” cuma masuk akal kalau layout-nya flex. Kalau grid, disembunyiin biar sidebar gak penuh sama setting yang gak relevan.

Yang mendukung visible_if: semua basic input setting, semua sidebar setting, dan specialized ini: color, color_background, color_scheme, font_picker, html, image_picker, inline_richtext, link_list, liquid, richtext, text_alignment, url, video, video_url. Yang gak ada di daftar (misalnya product, collection, metaobject, color_palette) gak bisa bersyarat.

Batasannya: visible_if gak bisa akses konteks runtime atau nilai dynamic source yang udah di-resolve. Kamu bisa ngecek apakah setting dengan dynamic source punya nilai, tapi gak bisa bikin kondisi berdasarkan hasil resolve-nya.

Setting yang Dikontrol Platform

Theme editor punya setting Custom CSS di level theme dan section yang gak bisa kamu tambahin atau sembunyiin. CSS yang diketik merchant disimpan di atribut custom_css, di section template JSON atau di object platform_customizations di settings_data.json. Sebagai developer, jangan nambahin atau ngedit nilai ini. Pakai aset CSS dan tag {% stylesheet %} sendiri, dan kasih opsi kustomisasi lewat theme setting.

Translasi Setting

Dua jenis translasi yang beda:

  1. Atribut schema (label, info, teks opsi) itu milik theme, ditranslasi lewat schema locale file (t: prefix) berdasarkan bahasa aktif toko, dibahas di 33 Locales dan Translasi.
  2. Nilai yang diisi merchant ditranslasi oleh merchant lewat app Translate & Adapt, buat setting berteks: text, textarea, richtext, inline_richtext, html. Nilai setting liquid gak bisa ditranslasi begini, makanya liquid cocok buat nilai netral bahasa (nama class CSS, kode integrasi app), walaupun Liquid-nya sendiri tetap bisa ngasilin output yang bergantung bahasa waktu render.

Input Settings: Atribut Standar

Hampir semua input setting punya atribut ini:

  1. type (wajib), tipe setting-nya.
  2. id (wajib), buat akses nilainya.
  3. label (wajib), label di theme editor.
  4. default, nilai awal.
  5. info, teks informasi tambahan.

Tergantung tipenya, ada atribut ekstra atau ada yang gak berlaku. Di info (dan content sidebar setting) kamu bisa nambahin link pakai sintaks Markdown [teks](url):

{
  "type": "checkbox",
  "id": "enable_payment_button",
  "label": "Show dynamic checkout button",
  "info": "Each customer will see their preferred payment method [Learn more](https://help.shopify.com/manual/online-store/dynamic-checkout)",
  "default": true
}

Basic Input Settings

Tujuh tipe dasar.

1. checkbox

Kotak centang, buat nyalain/matiin fitur:

{
  "type": "checkbox",
  "id": "show_announcement",
  "label": "Show announcement",
  "default": true
}

Nilainya boolean. Kalau default gak ada, nilainya false.

2. number

Satu field angka, misalnya jumlah produk per halaman:

{
  "type": "number",
  "id": "products_per_page",
  "label": "Products per page",
  "default": 20
}

Atribut ekstra: placeholder, tapi cuma tampil buat setting di settings_schema.json, gak di schema section. Nilainya number, atau nil kalau kosong. Hati-hati: default harus angka, bukan string, kalau gak, error.

❌ error

{ "type": "number", "id": "count", "label": "Count", "default": "20" }

✅ benar

{ "type": "number", "id": "count", "label": "Count", "default": 20 }

3. radio

Pilihan radio, atribut wajib options berisi array value/label:

{
  "type": "radio",
  "id": "logo_alignment",
  "label": "Logo alignment",
  "options": [
    {
      "value": "left",
      "label": "Left"
    },
    {
      "value": "centered",
      "label": "Centered"
    }
  ],
  "default": "left"
}

Nilainya string. Tanpa default, opsi pertama yang terpilih.

4. range

Slider plus field angka, misalnya ukuran font:

{
  "type": "range",
  "id": "font_size",
  "min": 12,
  "max": 24,
  "step": 1,
  "unit": "px",
  "label": "Font size",
  "default": 16
}

Atributnya: min (wajib), max (wajib), step (default 1), unit (misalnya px). Kalau merchant ngetik angka yang gak sesuai step, dibuletin ke step terdekat; kalau di luar min/max, dibalikin ke batasnya. Nilainya number. default wajib, dan min, max, step, default gak boleh string.

5. select

Dropdown atau segmented control, atribut wajib options, plus group opsional di tiap opsi buat ngelompokkin:

{
  "type": "select",
  "id": "vertical_alignment",
  "label": "Vertical alignment",
  "options": [
    {
      "value": "top",
      "label": "Top"
    },
    {
      "value": "middle",
      "label": "Middle"
    },
    {
      "value": "bottom",
      "label": "Bottom"
    }
  ],
  "default": "middle"
}

Bentuk tampilannya otomatis tergantung kriteria:

  1. SegmentedControl (tombol berjajar) kalau 2 sampai 5 opsi, gak pakai group, dan semua opsi muat di wadahnya.
  2. DropDown kalau pakai group, lebih dari 5 opsi, atau opsinya kepanjangan.

Jadi setting “Sizes” dengan enam opsi (xs sampai xxl) otomatis jadi dropdown. Nilainya string. Tanpa default, opsi pertama.

6. text

Satu baris teks, buat judul dan sejenisnya:

{
  "type": "text",
  "id": "footer_linklist_title",
  "label": "Heading",
  "default": "Quick links"
}

Atribut ekstra placeholder (cuma di settings_schema.json). Nilainya string, atau object empty kalau kosong. Catatan: setting text gak diperbarui waktu merchant ganti preset.

7. textarea

Teks multi baris, buat pesan panjang:

{
  "type": "textarea",
  "id": "home_welcome_message",
  "label": "Welcome message",
  "default": "Welcome to my shop!"
}

Sama kaya text: placeholder cuma di settings_schema.json, nilainya string atau empty.

Specialized Input Settings: Sumber Daya

Setting yang nunjuk ke data toko. Pola umumnya: nilainya object (atau array object), blank kalau kosong/hilang/disembunyiin, gak mendukung default, dan gak diperbarui waktu ganti preset. Output langsung ngembaliin handle (kompatibilitas legacy).

1. article

Pemilih artikel:

{
  "type": "article",
  "id": "article",
  "label": "Article"
}

Nilainya object article atau blank.

2. article_list

Pemilih banyak artikel, cuma yang udah dipublikasi. Atribut limit (default dan maksimum 50):

{
  "type": "article_list",
  "id": "featured_articles",
  "label": "Featured articles",
  "limit": 12
}

Nilainya array object article atau blank. Array-nya bisa dipaginasi pakai tag paginate, dan tambahin .count ke setting key buat dapat jumlahnya: section.settings.featured_articles.count.

3. blog

Pemilih blog:

{
  "type": "blog",
  "id": "blog",
  "label": "Blog"
}

Nilainya object blog atau blank.

4. collection

Pemilih koleksi:

{
  "type": "collection",
  "id": "collection",
  "label": "Collection"
}

Nilainya object collection atau blank.

5. collection_list

Pemilih banyak koleksi, limit default dan maksimum 50:

{
  "type": "collection_list",
  "id": "collection_list",
  "label": "Collections",
  "limit": 8
}

Nilainya array object collection atau blank, bisa dipaginasi, bisa .count.

6. page

Pemilih halaman, misalnya buat size chart:

{
  "type": "page",
  "id": "page",
  "label": "Page"
}

Nilainya object page atau blank.

7. product

Pemilih produk:

{
  "type": "product",
  "id": "product",
  "label": "Product"
}

Nilainya object product atau blank.

8. product_list

Pemilih banyak produk, cuma produk yang dipublikasi ke online store dan berstatus active. limit default dan maksimum 50:

{
  "type": "product_list",
  "id": "product_list",
  "label": "Products",
  "limit": 12
}

Nilainya array object product atau blank, bisa dipaginasi, bisa .count.

Pemilih menu, misalnya buat link footer:

{
  "type": "link_list",
  "id": "menu",
  "label": "Menu"
}

Nilainya object linklist atau blank. Ini satu-satunya setting sumber daya yang nerima default, tapi cuma main-menu dan footer (dua menu bawaan tiap toko).

10. metaobject

Pemilih satu entri metaobject dari tipe tertentu. Atribut wajib metaobject_type. Dua macam definisi:

  1. Standar, langsung tersedia di theme editor tanpa perlu diaktifin dulu, misalnya product_review atau shopify--material.
  2. Kustom, buat theme kustom, definisinya harus udah ada di toko. Gak boleh dipakai theme yang mau masuk Theme Store.
{
  "type": "metaobject",
  "id": "my_material_setting",
  "label": "Material",
  "metaobject_type": "shopify--material"
}
{
  "type": "metaobject",
  "id": "my_artist",
  "label": "Artist",
  "metaobject_type": "artist"
}

Nilainya object metaobject atau blank. Batasannya: cuma satu metaobject_type per setting; kalau tipe kustom atau milik app definisinya gak ada atau gak tersedia di storefront, setting-nya error di editor.

App juga bisa pakai ini di app block dengan definisi milik app (namespace app--). Contoh alur app testimoni: bikin definisi metaobject Customer Testimonial, kumpulin data lewat app block pasca pembelian, simpan sebagai entri metaobject, terus sediain app block “Testimonial” dengan setting metaobject bertipe app--<id>--testimonial, dan tampilin di Liquid.

11. metaobject_list

Sama kaya metaobject tapi banyak entri, plus limit (default dan maksimum 50):

{
  "type": "metaobject_list",
  "id": "my_material_list_setting",
  "label": "Materials",
  "metaobject_type": "shopify--material",
  "limit": 12
}

Nilainya array object metaobject atau blank, bisa dipaginasi, bisa .count. Batasan yang sama kaya metaobject.

Specialized Input Settings: Warna

1. color

Color picker, misalnya warna teks:

{
  "type": "color",
  "id": "heading_color",
  "label": "Heading color",
  "placeholder": "Default"
}

Atribut ekstra placeholder, teks yang tampil di picker waktu warna belum diset (misalnya “Default” atau “Inherited”), tanpa ngaruh ke nilai yang disimpan. Nilainya object color (bisa langsung dipakai filter warna dari 19 Filters HTML, URL, Media, Color, dan Font > Filter Warna) atau blank.

Kalau default gak ada, merchant lihat tombol Clear di editor. Clear nyimpen "" di settings_data.json dan ngembaliin blank di Liquid. Warna yang gak diset itu beda secara visual sama transparan (#00000000).

Kalau theme punya color_palette, default-nya bisa ngerujuk warna palet:

{
  "type": "color",
  "id": "heading_color",
  "label": "Heading color",
  "default": "{{ settings.colors.primary }}"
}

2. color_background

Field teks buat properti CSS background, misalnya gradien latar toko:

{
  "type": "color_background",
  "id": "background",
  "label": "Background",
  "default": "linear-gradient(#ffffff, #000000)"
}

Gak mendukung properti background yang berkaitan gambar. Nilainya string atau string kosong. Referensi palet juga bisa disisipkan di dalam string gradien:

{
  "type": "color_background",
  "id": "hero_gradient",
  "label": "Hero gradient",
  "default": "linear-gradient(180deg, {{ settings.colors.primary }}, {{ settings.colors.secondary }} 100%)"
}

3. color_palette

Definisiin sekumpulan warna bernama yang tersedia di semua setting color dan color_background theme. Merchant lihat warnanya sebagai grid di editor dan bisa milih dari situ waktu ngatur warna manapun.

Aturannya ketat: cuma satu color_palette per theme, harus di settings_schema.json, cuma mendukung atribut id (gak ada label, info, visible_if), dan default wajib berupa object key-value:

{
  "type": "color_palette",
  "id": "colors",
  "default": {
    "primary": "#121212",
    "secondary": "#FFFFFF",
    "accent": "#FF4416"
  }
}

Key harus diawali huruf, boleh huruf/angka/garis bawah. Nilai harus hex tanpa alpha (#FFF atau #FF4416, bukan 8 digit). Minimal 2, maksimal 20 warna, urutannya sesuai JSON. Perubahan merchant disimpan di settings_data.json dan menang atas default.

Aksesnya per key, tiap warna jadi object color:

{{ settings.colors.primary }}

Atau di-loop (cuma nilainya, key-nya gak tersedia waktu iterasi):

{% for color in settings.colors %}
  {{ color }}
{% endfor %}

Tiga perilaku penting:

  1. Referensi lintas setting: cuma path color_palette ({{ settings.colors.primary }}) yang boleh jadi default dinamis buat color dan color_background.
  2. Update theme: key baru di default palet otomatis muncul di palet merchant, nilai yang udah dikustomisasi merchant tetap dipertahankan.
  3. Hapus warna palet: waktu merchant ngehapus satu warna di editor, Shopify minta warna pengganti. Warna yang dihapus disimpan sebagai referensi ke penggantinya (misalnya {{ settings.colors.accent }}), jadi semua template yang makainya tetap utuh tanpa perlu diedit satu-satu.

4. color_scheme_group

Definisiin skema warna (sekumpulan warna yang dipakai bareng: latar, teks, tombol). Tersusun dari setting header, color, dan color_background. Cuma bisa di settings_schema.json:

{
  "type": "color_scheme_group",
  "id": "color_schemes",
  "definition": [
    {
      "type": "color",
      "id": "background",
      "label": "t:settings_schema.colors.settings.background.label",
      "default": "#FFFFFF"
    },
    {
      "type": "color_background",
      "id": "background_gradient",
      "label": "t:settings_schema.colors.settings.background_gradient.label",
      "info": "t:settings_schema.colors.settings.background_gradient.info"
    },
    {
      "type": "color",
      "id": "text",
      "label": "t:settings_schema.colors.settings.text.label",
      "default": "#121212"
    },
    {
      "type": "color",
      "id": "button",
      "label": "t:settings_schema.colors.settings.button_background.label",
      "default": "#121212"
    },
    {
      "type": "color",
      "id": "button_label",
      "label": "t:settings_schema.colors.settings.button_label.label",
      "default": "#FFFFFF"
    },
    {
      "type": "color",
      "id": "secondary_button_label",
      "label": "t:settings_schema.colors.settings.secondary_button_label.label",
      "default": "#121212"
    },
    {
      "type": "color",
      "id": "shadow",
      "label": "t:settings_schema.colors.settings.shadow.label",
      "default": "#121212"
    }
  ],
  "role": {
    "text": "text",
    "background": {
      "solid": "background",
      "gradient": "background_gradient"
    },
    "links": "secondary_button_label",
    "icons": "text",
    "primary_button": "button",
    "on_primary_button": "button_label",
    "primary_button_border": "button",
    "secondary_button": "background",
    "on_secondary_button": "secondary_button_label",
    "secondary_button_border": "secondary_button_label"
  }
}

definition itu daftar warna yang nyusun satu skema. role nge-map definisi ke preview skema yang dilihat merchant di manapun mereka milih skema warna (kotak kecil dengan latar, teks, dan dua pil tombol). Semua role wajib diisi:

  1. background, latar preview (boleh punya solid dan gradient).
  2. text, warna teks preview.
  3. primary_button dan secondary_button, pil pertama dan kedua (boleh gradien).
  4. primary_button_border dan secondary_button_border, border kedua pil.
  5. on_primary_button, on_secondary_button, links, icons, wajib ada tapi gak dipakai di preview.

5. color_scheme

Pemilih skema warna dari color_scheme_group, dengan preview. Bisa dipakai di section, block, dan theme setting, tapi gak didukung di app block:

{
  "type": "color_scheme",
  "id": "color_scheme",
  "default": "scheme_1",
  "label": "Color scheme"
}

Nilainya object color_scheme yang dipilih. Urutan fallback-nya: kalau nilainya kosong atau gak valid, pakai default; kalau default juga gak valid, pakai skema pertama di color_scheme_group; kalau theme gak punya data color_scheme_group di settings_data.json, nil.

Cara umum makainya: class di pembungkus section, color-{{ section.settings.color_scheme.id }}, dan CSS-nya digenerate dari loop skema di layout. Kita lihat polanya di 56 Design dan Color System.

Specialized Input Settings: Teks dan Kode

1. richtext

Editor teks kaya: bold, italic, underline, link, paragraf, daftar tak berurut:

{
  "type": "richtext",
  "id": "paragraph",
  "label": "Paragraph"
}

Tombol underline gak ada di komponennya, tapi merchant bisa pakai Cmd+U/Ctrl+U. Nilainya string berisi HTML, atau empty.

default-nya punya aturan: elemen level atas cuma boleh <p> atau <ul>, dan di dalam <p> cuma boleh <p>, <br />, <strong>, <b>, <em>, <i>, <u>, <span>, <a>. Default yang gak dibungkus <p> atau <ul> bikin error.

❌ error

{ "type": "richtext", "id": "text", "label": "Text", "default": "Hello world" }

✅ benar

{ "type": "richtext", "id": "text", "label": "Text", "default": "<p>Hello world</p>" }

2. inline_richtext

HTML tanpa pembungkus <p>, buat teks satu baris yang butuh format: bold, italic, link. Gak mendukung line break (<br />) dan gak ada tombol underline (shortcut tetap jalan):

{
  "type": "inline_richtext",
  "id": "inline",
  "default": "my inline text",
  "label": "Inline rich text"
}

Nilainya string atau empty. Cocok buat heading yang sebagian katanya mau ditebelin.

3. html

Field multi baris yang nerima HTML mentah, misalnya embed video:

{
  "type": "html",
  "id": "video_embed",
  "label": "Video embed"
}

Atribut ekstra placeholder. Tag <html>, <head>, <body> dibuang otomatis, dan tag yang gak ditutup ditutup otomatis waktu disimpan (bisa beda dari maksud kamu, jadi cek). Nilainya string atau empty.

4. liquid

Field multi baris yang nerima HTML dan Liquid terbatas, misalnya pesan khusus produk atau kode integrasi app:

{
  "type": "liquid",
  "id": "battery_message",
  "label": "Battery message",
  "default": "{% if product.tags contains 'battery' %}This product can only be shipped by ground.{% else %}This product can be shipped by ground or air.{% endif %}"
}

Nilainya string atau empty. default opsional tapi gak boleh string kosong, dan tag yang gak ditutup ditutup otomatis.

Batasannya, setting liquid gak punya akses ke: layout, content_for_header, content_for_layout, content_for_index, tag section, javascript, stylesheet, schema, dan object settings. Yang bisa: object global, object template (product, collection di template masing-masing), dan tag serta filter standar. Tag yang gak ada dirender jadi string kosong:

{
  "type": "liquid",
  "id": "message",
  "label": "Message",
  "default": "Hello {{ not_a_real_tag }}, welcome to our shop."
}

Hasilnya Hello , welcome to our shop.. Batas isinya 50kb, dan Liquid yang gak valid bikin error waktu disimpan.

Specialized Input Settings: Media dan Font

1. image_picker

Pemilih gambar dari Files di admin, bisa upload baru, dan merchant bisa ngisi alt text dan focal point:

{
  "type": "image_picker",
  "id": "image_with_text_image",
  "label": "Image"
}

Nilainya object image atau nil. Gak mendukung default dan gak diperbarui waktu ganti preset.

Focal point itu titik di gambar yang merchant mau tetap kelihatan waktu gambarnya di-crop. Biar theme kamu ngehormatinnya: render pakai filter image_tag dari 19 Filters HTML, URL, Media, Color, dan Font > 2. image_tag dan posisiin gambar di wadahnya pakai object-fit: cover:

{{ section.settings.image_with_text_image | image_url: width: 1500 | image_tag }}

Kalau focal point ada, image_tag otomatis nambahin style="object-position: 25% 10%" (sesuai titiknya). Kalau mau nimpa buat kasus tertentu, kasih style: 'object-position: inherit;' ke image_tag. Data mentahnya juga ada di image.presentation.focal_point.

2. video

Pemilih video yang di-host Shopify dari Files, bisa upload baru:

{
  "type": "video",
  "id": "video",
  "label": "A Shopify-hosted video"
}

Nilainya object video atau nil (gak dipilih, udah hilang, atau dynamic source-nya metafield file_reference yang nunjuk ke bukan video). Nerima metafield file_reference sebagai dynamic source. Gak mendukung default.

3. video_url

Field URL buat video YouTube dan/atau Vimeo. Atribut wajib accept, array provider yang diterima:

{
  "type": "video_url",
  "id": "product_description_video",
  "label": "Product description video",
  "accept": [
    "youtube",
    "vimeo"
  ]
}

Nilainya string URL atau nil. Bonusnya, kamu dapat id dan type videonya:

ID: {{ settings.product_description_video.id }}
Type: {{ settings.product_description_video.type }}

Buat https://www.youtube.com/watch?v=_9VUPq3SxOc hasilnya ID: _9VUPq3SxOc dan Type: youtube. Ini yang kamu butuhin buat nyusun URL embed sendiri.

4. font_picker

Pemilih font dari Shopify font library (font sistem dan pilihan Google Fonts):

{
  "type": "font_picker",
  "id": "heading_font",
  "label": "Heading font",
  "default": "helvetica_n4"
}

Nilainya object font, yang dipakai bareng filter font_face, font_url, font_modify dari 19 Filters HTML, URL, Media, Color, dan Font > Filter Font. default wajib, nilainya handle font dari library (format nama_n4 = normal weight 400). Daftar font dan cara pakainya di 31 Dynamic Sources dan Fonts.

Specialized Input Settings: Lainnya

1. text_alignment

SegmentedControl berikon buat perataan teks:

{
   "type": "text_alignment",
   "id": "alignment",
   "label": "Text alignment",
   "default": "center"
}

Nilainya string left, center, atau right. Opsinya tetap, gak bisa diubah. Tanpa default, left.

2. url

Field URL yang nerima URL eksternal atau path relatif, plus picker buat artikel, blog, koleksi, halaman, dan produk. Cocok buat link tombol:

{
  "type": "url",
  "id": "button_link",
  "label": "Button link"
}

Nilainya string atau nil. default cuma nerima /collections dan /collections/all.

Setting yang gak nyimpen nilai, cuma buat ngerapiin dan ngasih penjelasan. Atributnya type (wajib) dan content (wajib). Dua-duanya mendukung visible_if.

1. header

Judul pengelompokan, dengan info opsional (yang juga bisa berisi link Markdown):

{
  "type": "header",
  "content": "Email Signup",
  "info": "Subscribers added automatically to your \"accepted marketing\" customer list. [Learn more](https://help.shopify.com/manual/customers/manage-customers)"
}

2. paragraph

Teks penjelasan biasa:

{
  "type": "paragraph",
  "content": "All of your collections are listed by default. To customize your list, choose 'Selected' and add collections."
}

Pola bagusnya: satu header per kelompok setting (Layout, Colors, Typography), info di setting yang butuh konteks, dan paragraph cuma buat penjelasan yang gak nempel ke satu setting tertentu. Sidebar yang rapi itu bagian dari kualitas theme, dan dinilai waktu review Theme Store di 70 Theme Store Gambaran dan Requirements.

Cheat Sheet Nilai Balik

Biar gampang diingat, ini yang kamu dapat di Liquid:

  1. Boolean: checkbox.
  2. Number (atau nil): number, range.
  3. String (atau empty): text, textarea, richtext, inline_richtext, html, liquid.
  4. String (tanpa empty): radio, select, text_alignment, color_background.
  5. String (atau nil): url, video_url (plus .id dan .type).
  6. Object (atau blank): article, blog, collection, page, product, link_list, metaobject, color.
  7. Array object (atau blank, bisa paginate dan .count): article_list, collection_list, product_list, metaobject_list.
  8. Object (atau nil): image_picker, video.
  9. Object khusus: font_picker → font, color_scheme → color_scheme, color_palette → kumpulan color.

Ringkasan

  1. Setting ada di tiga level (theme lewat settings_schema.json, section dan block lewat {% schema %}), diakses lewat settings, section.settings, block.settings plus id-nya.
  2. Dua kategori: input setting (nyimpen nilai) dan sidebar setting (header, paragraph, cuma informasi).
  3. Selalu cek blank sebelum pakai nilai, terutama setting sumber daya yang bisa kosong, terhapus, atau disembunyiin. Output langsung setting sumber daya ngembaliin handle (legacy), tapi propertinya langsung bisa diakses.
  4. visible_if nyembunyiin setting berdasarkan setting lain, didukung semua basic dan sidebar setting plus sebagian specialized, tapi gak bisa baca nilai dynamic source yang udah di-resolve.
  5. Atribut standar: type, id, label wajib, default dan info opsional, info bisa berisi link Markdown.
  6. Basic: checkbox, number, radio, range, select, text, textarea. number dan range gak boleh pakai string, range wajib default, select otomatis jadi segmented (2–5 opsi) atau dropdown.
  7. Sumber daya (article, blog, collection, page, product, link_list, metaobject dan versi _list-nya) ngembaliin object atau blank, gak mendukung default (kecuali link_list), gak diperbarui waktu ganti preset, _list maksimal 50 dan bisa dipaginasi.
  8. Warna: color (object color, placeholder, Clear kalau tanpa default), color_background (string CSS), color_palette (satu per theme di settings_schema.json, 2–20 hex tanpa alpha, bisa jadi default color), color_scheme_group (definisi + role buat preview), color_scheme (pemilih, gak di app block).
  9. Teks dan kode: richtext (default wajib dibungkus <p>/<ul>), inline_richtext (tanpa <p>, tanpa <br>), html (buang <html>/<head>/<body>), liquid (Liquid terbatas, maksimal 50kb, gak bisa akses settings dan tag layout).
  10. Media dan font: image_picker (object image, focal point lewat image_tag), video (Shopify-hosted), video_url (YouTube/Vimeo, accept wajib, dapat .id dan .type), font_picker (default wajib).
  11. text_alignment string left/center/right, url string dengan picker sumber daya.
  12. Translasi: atribut schema lewat locale file t:, nilai merchant lewat Translate & Adapt (kecuali liquid).

Bab selanjutnya kita bahas dua hal yang nyambung ke setting: dynamic sources, cara merchant nyambungin setting ke metafield dan data toko, dan sistem font Shopify, dari font library sampai cara load font yang bener.