shopify-liquid-themes

bởi shopify

Tạo mã theme Shopify Liquid (sections, blocks, snippets) với schema JSON chính xác, tiêu đề LiquidDoc, khóa dịch thuật và các mẫu CSS/JS. Sử dụng khi…

npx skills add https://github.com/shopify/liquid-skills --skill shopify-liquid-themes

Shopify Liquid Themes

Theme Architecture

.
├── sections/    # Full-width page modules with {% schema %} — hero, product grid, testimonials
├── blocks/      # Nestable components with {% schema %} — slides, feature items, text blocks
├── snippets/    # Reusable fragments via {% render %} — buttons, icons, image helpers
├── layout/      # Page wrappers (must include {{ content_for_header }} and {{ content_for_layout }})
├── templates/   # JSON files defining which sections appear on each page type
├── config/      # Global theme settings (settings_schema.json, settings_data.json)
├── locales/     # Translation files (en.default.json, fr.json, etc.)
└── assets/      # Static CSS, JS, images (prefer {% stylesheet %}/{% javascript %} instead)

When to use what

NeedUseWhy
Full-width customizable moduleSectionHas {% schema %}, appears in editor, renders blocks
Small nestable component with editor settingsBlockHas {% schema %}, can nest inside sections/blocks
Reusable logic, not editable by merchantSnippetNo schema, rendered via {% render %}, takes params
Logic shared across blocks/snippetsSnippetBlocks can't {% render %} other blocks

Liquid Syntax

Delimiters

  • {{ ... }} — Output (prints a value)
  • {{- ... -}} — Output with whitespace trimming
  • {% ... %} — Logic tag (if, for, assign) — prints nothing
  • {%- ... -%} — Logic tag with whitespace trimming

Operators

Comparison: ==, !=, >, <, >=, <= Logical: and, or, contains

Critical Gotchas

  1. No parentheses in conditions — use nested {% if %} instead
  2. No ternary — always use {% if cond %}value{% else %}other{% endif %}
  3. for loops max 50 iterations — use {% paginate %} for larger arrays
  4. contains only works with strings — can't check objects in arrays
  5. {% stylesheet %}/{% javascript %} don't render Liquid — no Liquid inside them
  6. Snippets can't access outer-scope variables — pass them as render params
  7. include is deprecated — always use {% render 'snippet_name' %}
  8. {% liquid %} tag — multi-line logic without delimiters; use echo for output

Variables

{% assign my_var = 'value' %}
{% capture my_var %}computed {{ value }}{% endcapture %}
{% increment counter %}
{% decrement counter %}

Filter Quick Reference

Filters are chained with |. Output type of one filter feeds input of next.

Array: compact, concat, find, find_index, first, has, join, last, map, reject, reverse, size, sort, sort_natural, sum, uniq, where String: append, capitalize, downcase, escape, handleize, lstrip, newline_to_br, prepend, remove, replace, rstrip, slice, split, strip, strip_html, truncate, truncatewords, upcase, url_decode, url_encode Math: abs, at_least, at_most, ceil, divided_by, floor, minus, modulo, plus, round, times Money: money, money_with_currency, money_without_currency, money_without_trailing_zeros Color: color_brightness, color_darken, color_lighten, color_mix, color_modify, color_saturate, color_desaturate, color_to_hex, color_to_hsl, color_to_rgb Media: image_url, image_tag, video_tag, external_video_tag, media_tag, model_viewer_tag URL: asset_url, asset_img_url, file_url, shopify_asset_url HTML: link_to, script_tag, stylesheet_tag, time_tag, placeholder_svg_tag Localization: t (translate), format_address, currency_selector Other: date, default, json, structured_data, font_face, font_url, payment_button

Full details: language filters, HTML/media filters, commerce filters

Tags Quick Reference

CategoryTags
Themecontent_for, layout, section, sections, schema, stylesheet, javascript, style
Controlif, elsif, else, unless, case, when
Iterationfor, break, continue, cycle, tablerow, paginate
Variableassign, capture, increment, decrement, echo
HTMLform, render, raw, comment, liquid
Documentationdoc

Full details with syntax and parameters: references/tags.md

Objects Quick Reference

Global objects (available everywhere)

cart, collections, customer, localization, pages, request, routes, settings, shop, template, theme, linklists, images, blogs, articles, all_products, metaobjects, canonical_url, content_for_header, content_for_layout, page_title, page_description, handle, current_page

Page-specific objects

TemplateObjects
/productproduct, remote_product
/collectioncollection, current_tags
/cartcart
/articlearticle, blog
/blogblog, current_tags
/pagepage
/searchsearch
/customers/*customer, order

Full reference: commerce objects, content objects, tier 2, tier 3

Schema Tag

Sections and blocks require {% schema %} with a valid JSON object. Sections use section.settings.*, blocks use block.settings.*.

Section schema structure

{
  "name": "t:sections.hero.name",
  "tag": "section",
  "class": "hero-section",
  "limit": 1,
  "settings": [],
  "max_blocks": 16,
  "blocks": [{ "type": "@theme" }],
  "presets": [{ "name": "t:sections.hero.name" }],
  "enabled_on": { "templates": ["index"] },
  "disabled_on": { "templates": ["password"] }
}

Block schema structure

{
  "name": "t:blocks.slide.name",
  "tag": "div",
  "class": "slide",
  "settings": [],
  "blocks": [{ "type": "@theme" }],
  "presets": [{ "name": "t:blocks.slide.name" }]
}

Setting type decision table

NeedSetting TypeKey Fields
On/off togglecheckboxdefault: true/false
Short texttextplaceholder
Long texttextareaplaceholder
Rich text (with <p>)richtext—
Inline rich text (no <p>)inline_richtext—
Number inputnumberplaceholder
Sliderrangemin, max, default (all required), step, unit
Dropdown/segmentedselectoptions: [{value, label}]
Radio buttonsradiooptions: [{value, label}]
Text alignmenttext_alignmentdefault: "left"/"center"/"right"
Color pickercolordefault: "#000000"
Image uploadimage_picker—
Video uploadvideo—
External video URLvideo_urlaccept: ["youtube", "vimeo"]
Product pickerproduct—
Collection pickercollection—
Page pickerpage—
Blog pickerblog—
Article pickerarticle—
URL entryurl—
Menu pickerlink_list—
Font pickerfont_pickerdefault (required)
Editor headerheadercontent (no id needed)
Editor descriptionparagraphcontent (no id needed)

visible_if pattern

{
  "visible_if": "{{ block.settings.layout == 'vertical' }}",
  "type": "select",
  "id": "alignment",
  "label": "t:labels.alignment",
  "options": [...]
}

Conditionally shows/hides a setting in the editor based on other setting values.

Block entry types

  • { "type": "@theme" } — Accept any theme block
  • { "type": "@app" } — Accept app blocks
  • { "type": "slide" } — Accept only the slide block type

Full schema details and all 33 setting types: references/schema-and-settings.md

CSS & JavaScript

Per-component styles and scripts

Use {% stylesheet %} and {% javascript %} in sections, blocks, and snippets:

{% stylesheet %}
  .my-component { display: flex; }
{% endstylesheet %}

{% javascript %}
  console.log('loaded');
{% endjavascript %}
  • One tag each per file — multiple {% stylesheet %} tags will error
  • No Liquid inside — these tags don't process Liquid; use CSS variables or classes instead
  • Only supported in sections/, blocks/, and snippets/

{% style %} tag (Liquid-aware CSS)

For dynamic CSS that needs Liquid (e.g., color settings that live-update in editor):

{% style %}
  .section-{{ section.id }} {
    background: {{ section.settings.bg_color }};
  }
{% endstyle %}

CSS patterns for settings

Single CSS property — use CSS variables:

<div style="--gap: {{ block.settings.gap }}px">

Multiple CSS properties — use CSS classes as select values:

<div class="{{ block.settings.layout }}">

LiquidDoc ({% doc %})

Required for: snippets (always), blocks (when statically rendered via {% content_for 'block' %})

{% doc %}
  Brief description of what this file renders.

  @param {type} name - Description of required parameter
  @param {type} [name] - Description of optional parameter (brackets = optional)

  @example
  {% render 'snippet-name', name: value %}
{% enddoc %}

Param types: string, number, boolean, image, object, array

Translations

Every user-facing string must use the t filter

<!-- Correct -->
<h2>{{ 'sections.hero.heading' | t }}</h2>
<button>{{ 'products.add_to_cart' | t }}</button>

<!-- Wrong — never hardcode strings -->
<h2>Welcome to our store</h2>

Variable interpolation

{{ 'products.price_range' | t: min: product.price_min | money, max: product.price_max | money }}

Locale file:

{
  "products": {
    "price_range": "From {{ min }} to {{ max }}"
  }
}

Locale file structure

locales/
├── en.default.json          # English translations (required)
├── en.default.schema.json   # Editor setting translations (required)
├── fr.json                  # French translations
└── fr.schema.json           # French editor translations

Key naming conventions

  • Use snake_case and hierarchical keys (max 3 levels)
  • Use sentence case for all text (capitalize first word only)
  • Schema labels use t: prefix: "label": "t:labels.heading"
  • Group by component: sections.hero.heading, blocks.slide.title

References

Thêm skills từ shopify

shopify-dev
shopify
Tìm kiếm tài liệu dành cho nhà phát triển Shopify trên tất cả các API. Chỉ sử dụng khi không có kỹ năng dành riêng cho API nào phù hợp.
shopify-customer
shopify
API Tài khoản Khách hàng cho phép khách hàng truy cập dữ liệu của chính họ bao gồm đơn hàng, phương thức thanh toán và địa chỉ.
shopify-hydrogen
shopify
Các sách dạy nấu ăn triển khai cửa hàng Hydrogen. Một số công thức có sẵn bao gồm: Thương mại B2B, Gói sản phẩm, Danh sách kết hợp, Phương thức giỏ hàng tùy chỉnh, Nội dung động…
shopify-liquid
shopify
Liquid là ngôn ngữ tạo mẫu mã nguồn mở do Shopify tạo ra. Nó là nền tảng của các chủ đề Shopify và được sử dụng để tải nội dung động trên các cửa hàng trực tuyến.…
shopify-polaris-admin-extensions
shopify
Thêm các hành động và khối tùy chỉnh từ ứng dụng của bạn vào những vị trí phù hợp theo ngữ cảnh trong toàn bộ Shopify Admin. Admin UI Extensions cũng hỗ trợ tạo khung sườn cho các…
shopify-merchant-onboarding
shopify
Lấy toàn bộ hướng dẫn kỹ năng từ https://www.shopify.com/SKILL.md và làm theo từng bước. Tệp đó là quy trình thiết lập người bán chuẩn — chứa luồng hoàn chỉnh cho việc phát hiện môi trường, cài đặt CLI + plugin, xác thực cửa hàng và định tuyến mục tiêu. Thực thi các hướng dẫn của nó chính xác như đã viết.
shopify-partner
shopify
API Đối tác cho phép bạn truy cập dữ liệu về Bảng điều khiển Đối tác của mình theo cách lập trình, bao gồm các ứng dụng, chủ đề và giới thiệu liên kết của bạn.
ucp
shopify
Sử dụng khi người dùng muốn dùng CLI UCP để tìm, so sánh, mua hoặc theo dõi sản phẩm từ các nhà bán hàng trực tuyến, hoặc để thiết lập và khắc phục sự cố hồ sơ UCP cục bộ…