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.
What this skill does
# 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
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
```liquid
{% 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](references/filters-language.md), [HTML/media filters](references/filters-html-media.md), [commerce filters](references/filters-commerce.md)
## 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](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](references/objects-commerce.md), [content objects](references/objects-content.md), [tier 2](references/objects-tier2.md), [tier 3](references/objects-tier3.md)
## Schema Tag
Sections and blocks require `{% schema %}` with a valid JSON object. Sections use `section.settings.*`, blocks use `block.settings.*`.
### Section schema structure
```json
{
"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
```json
{
"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
```json
{
"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](references/schema-and-sRelated in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.