
shopify-liquid-themes
Generate Shopify Liquid theme code (sections, blocks, snippets) with correct schema JSON, LiquidDoc headers, translation keys, and CSS/JS patterns. Use when creating or editing .liquid files for Shopify themes, working with schema, doc, stylesheet, javascript tags, or Shopify Liquid objects/filters/tags.
- Installs
- 3.7K
- Last 24h
- +30
- Trending rank
- #4370
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/benjaminsehl/liquid-skills --skill shopify-liquid-themes- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads shopify-liquid-themes automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
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
| Need | Use | Why |
|---|---|---|
| Full-width customizable module | Section | Has {% schema %}, appears in editor, renders blocks |
| Small nestable component with editor settings | Block | Has {% schema %}, can nest inside sections/blocks |
| Reusable logic, not editable by merchant | Snippet | No schema, rendered via {% render %}, takes params |
| Logic shared across blocks/snippets | Snippet | Blocks 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
- No parentheses in conditions — use nested
{% if %}instead - No ternary — always use
{% if cond %}value{% else %}other{% endif %} forloops max 50 iterations — use{% paginate %}for larger arrayscontainsonly works with strings — can't check objects in arrays{% stylesheet %}/{% javascript %}don't render Liquid — no Liquid inside them- Snippets can't access outer-scope variables — pass them as render params
includeis deprecated — always use{% render 'snippet_name' %}{% liquid %}tag — multi-line logic without delimiters; useechofor 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
| Category | Tags |
|---|---|
| Theme | content_for, layout, section, sections, schema, stylesheet, javascript, style |
| Control | if, elsif, else, unless, case, when |
| Iteration | for, break, continue, cycle, tablerow, paginate |
| Variable | assign, capture, increment, decrement, echo |
| HTML | form, render, raw, comment, liquid |
| Documentation | doc |
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
| Template | Objects |
|---|---|
/product | product, remote_product |
/collection | collection, current_tags |
/cart | cart |
/article | article, blog |
/blog | blog, current_tags |
/page | page |
/search | search |
/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
| Need | Setting Type | Key Fields |
|---|---|---|
| On/off toggle | checkbox | default: true/false |
| Short text | text | placeholder |
| Long text | textarea | placeholder |
Rich text (with <p>) | richtext | — |
Inline rich text (no <p>) | inline_richtext | — |
| Number input | number | placeholder |
| Slider | range | min, max, default (all required), step, unit |
| Dropdown/segmented | select | options: [{value, label}] |
| Radio buttons | radio | options: [{value, label}] |
| Text alignment | text_alignment | default: "left"/"center"/"right" |
| Color picker | color | default: "#000000" |
| Image upload | image_picker | — |
| Video upload | video | — |
| External video URL | video_url | accept: ["youtube", "vimeo"] |
| Product picker | product | — |
| Collection picker | collection | — |
| Page picker | page | — |
| Blog picker | blog | — |
| Article picker | article | — |
| URL entry | url | — |
| Menu picker | link_list | — |
| Font picker | font_picker | default (required) |
| Editor header | header | content (no id needed) |
| Editor description | paragraph | content (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 theslideblock 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/, andsnippets/
{% 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
- Filters: language (77), HTML/media (45), commerce (30)
- Tag reference (30 tags)
- Objects: commerce (5), content (10), tier 2 (69), tier 3 (53)
- Schema & settings reference (33 types)
- Complete examples (snippet, block, section)
FAQ
What does the shopify-liquid-themes skill do?
Generate Shopify Liquid theme code (sections, blocks, snippets) with correct schema JSON, LiquidDoc headers, translation keys, and CSS/JS patterns. Use when creating or editing .liquid files for Shopify themes, working with schema, doc, stylesheet, javascript tags, or Shopify Liquid objects/filters/tags.
How do I install shopify-liquid-themes?
Run npx skills add https://github.com/benjaminsehl/liquid-skills --skill shopify-liquid-themes in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/shopify-liquid-themes/ (personal) or .claude/skills/shopify-liquid-themes/ (project).
Which AI agents can use shopify-liquid-themes?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is shopify-liquid-themes safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains shopify-liquid-themes?
It is published by benjaminsehl in benjaminsehl/liquid-skills. It has 3,660 recorded installs.
More from benjaminsehl/liquid-skills
liquid-theme-standards
benjaminsehl/liquid-skills
CSS, JavaScript, and HTML coding standards for Shopify Liquid themes. Covers BEM naming inside stylesheet tags, design tokens, CSS custom properties, Web Components for themes, defensive CSS, and progressive enhancement. Use when writing CSS/JS/HTML in .liquid files or theme asset files.
liquid-theme-a11y
benjaminsehl/liquid-skills
Implement WCAG 2.2 accessibility patterns in Shopify Liquid themes. Covers e-commerce-specific components including product cards, carousels, cart drawers, price display, forms, filters, and modals. Use when building accessible theme components, fixing accessibility issues, or reviewing ARIA patterns in .liquid files.
Popular business & finance skills
sales-enablement
coreyhaines31/marketingskills
When the user wants to create sales collateral, pitch decks, one-pagers, objection handling docs, or demo scripts. Also use when the user mentions 'sales deck,' 'pitch deck,' 'one-pager,' 'leave-behind,' 'objection handling,' 'deal-specific ROI analysis,' 'demo script,' 'talk track,' 'sales playbook,' 'proposal template,' 'buyer persona card,' 'battle card,' 'battlecard,' 'competitive one-pager,' 'win-loss analysis,' 'why are we losing deals,' 'loss reasons,' 'how do I respond to this objection,' 'prospect just said,' 'help my sales team,' 'sales materials,' or 'what should I give my sales reps,' 'cold call script,' or 'voicemail script.' Use this for any document or asset that helps a sales team close deals. For public competitor comparison pages, see competitors. For running buyer interviews or churn research, see customer-research. For marketing website copy, see copywriting. For cold outreach emails, see cold-email. For the offer being sold (bonuses, guarantees, pricing structure),
revops
coreyhaines31/marketingskills
When the user wants help with revenue operations, lead lifecycle management, or marketing-to-sales handoff processes. Also use when the user mentions 'RevOps,' 'revenue operations,' 'lead scoring,' 'outbound pipeline stages,' 'lead routing,' 'MQL,' 'SQL,' 'pipeline stages,' 'deal desk,' 'CRM automation,' 'marketing-to-sales handoff,' 'data hygiene,' 'leads aren't getting to sales,' 'pipeline management,' 'lead qualification,' or 'when should marketing hand off to sales.' Use this for anything involving the systems and processes that connect marketing to revenue. For cold outreach emails, see cold-email. For email drip campaigns, see emails. For pricing decisions, see pricing.
sales-funnel-blueprint
autonnel/autonnel-skills
Turn an offer into a concrete multi-step sales funnel spec - page-by-page structure, price ladder, copy outline and the metrics each step must hit. Use when asked to build a sales funnel, marketing funnel, landing page flow, lead magnet funnel, webinar funnel, tripwire or VSL funnel, when planning a product launch page flow, or when someone asks "what pages do I need" for selling something online.
pricing
coreyhaines31/marketingskills
When the user wants help with pricing decisions, packaging, or monetization strategy. Also use when the user mentions 'pricing,' 'pricing tiers,' 'freemium,' 'free trial,' 'packaging,' 'price increase,' 'value metric,' 'Van Westendorp,' 'willingness to pay,' 'monetization,' 'how much should I charge,' 'my pricing is wrong,' 'pricing page,' 'annual vs monthly,' 'per seat pricing,' 'should I offer a free plan,' 'pricing page teardown,' 'pricing page audit,' 'is my pricing page AI-readable,' or 'can AI read my pricing.' Use this whenever someone is figuring out what to charge, how to structure their plans, or wants to audit a pricing page (for humans and for the AI agents that shortlist tools). For in-app upgrade screens, see paywalls. For offer construction (bonuses, guarantees, value framing, naming) on services/courses/coaching/high-ticket B2B, see offers.
cross-border-ecommerce
nexscope-ai/ecommerce-skills
Cross-border e-commerce expansion advisor. Scores target markets on 8 weighted dimensions (market size, ecommerce penetration, competition, regulatory complexity, logistics infrastructure, payment ecosystem, cultural distance, IP protection), compares 5 fulfillment models with cost and transit data, provides country-by-country tax/duty compliance guides (EU VAT/IOSS, UK VAT, US sales tax, CA GST, AU GST, JP consumption tax), maps local payment preferences by market, and builds a phased expansion roadmap. No API key required.
pricing-strategy
coreyhaines31/marketingskills
When the user wants help with pricing decisions, packaging, or monetization strategy. Also use when the user mentions 'pricing,' 'pricing tiers,' 'freemium,' 'free trial,' 'packaging,' 'price increase,' 'value metric,' 'Van Westendorp,' 'willingness to pay,' 'monetization,' 'how much should I charge,' 'my pricing is wrong,' 'pricing page,' 'annual vs monthly,' 'per seat pricing,' or 'should I offer a free plan.' Use this whenever someone is figuring out what to charge or how to structure their plans. For in-app upgrade screens, see paywall-upgrade-cro.