[ PROMPT_NODE_28035 ]
Themes
[ SKILL_DOCUMENTATION ]
# Themes Reference
Guide for developing Shopify themes with Liquid templating.
## Liquid Templating
### Syntax Basics
**Objects (Output):**
```liquid
{{ product.title }}
{{ product.price | money }}
{{ customer.email }}
```
**Tags (Logic):**
```liquid
{% if product.available %}
{% else %}
{{ page_title }}
{{ content_for_header }}
{% section 'header' %}
{{ content_for_layout }}
{% section 'footer' %}
```
### Templates
Page-specific structures (`templates/product.json`):
```json
{
"sections": {
"main": {
"type": "product-template",
"settings": {
"show_vendor": true,
"show_quantity_selector": true
}
},
"recommendations": {
"type": "product-recommendations"
}
},
"order": ["main", "recommendations"]
}
```
Legacy format (`templates/product.liquid`):
```liquid
```
### Sections
Reusable content blocks (`sections/product-grid.liquid`):
```liquid
Sold Out
{% endif %} {% for product in collection.products %} {{ product.title }} {% endfor %} {% case product.type %} {% when 'Clothing' %} Apparel {% when 'Shoes' %} Footwear {% else %} Other {% endcase %} ``` **Filters (Transform):** ```liquid {{ product.title | upcase }} {{ product.price | money }} {{ product.description | strip_html | truncate: 100 }} {{ product.image | img_url: 'medium' }} {{ 'now' | date: '%B %d, %Y' }} ``` ### Common Objects **Product:** ```liquid {{ product.id }} {{ product.title }} {{ product.handle }} {{ product.description }} {{ product.price }} {{ product.compare_at_price }} {{ product.available }} {{ product.type }} {{ product.vendor }} {{ product.tags }} {{ product.images }} {{ product.variants }} {{ product.featured_image }} {{ product.url }} ``` **Collection:** ```liquid {{ collection.title }} {{ collection.handle }} {{ collection.description }} {{ collection.products }} {{ collection.products_count }} {{ collection.image }} {{ collection.url }} ``` **Cart:** ```liquid {{ cart.item_count }} {{ cart.total_price }} {{ cart.items }} {{ cart.note }} {{ cart.attributes }} ``` **Customer:** ```liquid {{ customer.email }} {{ customer.first_name }} {{ customer.last_name }} {{ customer.orders_count }} {{ customer.total_spent }} {{ customer.addresses }} {{ customer.default_address }} ``` **Shop:** ```liquid {{ shop.name }} {{ shop.email }} {{ shop.domain }} {{ shop.currency }} {{ shop.money_format }} {{ shop.enabled_payment_types }} ``` ### Common Filters **String:** - `upcase`, `downcase`, `capitalize` - `strip_html`, `strip_newlines` - `truncate: 100`, `truncatewords: 20` - `replace: 'old', 'new'` **Number:** - `money` - Format currency - `round`, `ceil`, `floor` - `times`, `divided_by`, `plus`, `minus` **Array:** - `join: ', '` - `first`, `last` - `size` - `map: 'property'` - `where: 'property', 'value'` **URL:** - `img_url: 'size'` - Image URL - `url_for_type`, `url_for_vendor` - `link_to`, `link_to_type` **Date:** - `date: '%B %d, %Y'` ## Theme Architecture ### Directory Structure ``` theme/ ├── assets/ # CSS, JS, images ├── config/ # Theme settings │ ├── settings_schema.json │ └── settings_data.json ├── layout/ # Base templates │ └── theme.liquid ├── locales/ # Translations │ └── en.default.json ├── sections/ # Reusable blocks │ ├── header.liquid │ ├── footer.liquid │ └── product-grid.liquid ├── snippets/ # Small components │ ├── product-card.liquid │ └── icon.liquid └── templates/ # Page templates ├── index.json ├── product.json ├── collection.json └── cart.liquid ``` ### Layout Base template wrapping all pages (`layout/theme.liquid`): ```liquid{{ product.title }}
{{ product.price | money }}
{% form 'product', product %} {% for variant in product.variants %} {{ variant.title }} - {{ variant.price | money }} {% endfor %} {% endform %}
{% for product in section.settings.collection.products %}
{% endfor %}
{% schema %}
{
"name": "Product Grid",
"settings": [
{
"type": "collection",
"id": "collection",
"label": "Collection"
},
{
"type": "range",
"id": "products_per_row",
"min": 2,
"max": 5,
"step": 1,
"default": 4,
"label": "Products per row"
}
],
"presets": [
{
"name": "Product Grid"
}
]
}
{% endschema %}
```
### Snippets
Small reusable components (`snippets/product-card.liquid`):
```liquid
```
Include snippet:
```liquid
{% render 'product-card', product: product %}
```
## Development Workflow
### Setup
```bash
# Initialize new theme
shopify theme init
# Choose Dawn (reference theme) or blank
```
### Local Development
```bash
# Start local server
shopify theme dev
# Preview at http://localhost:9292
# Changes auto-sync to development theme
```
### Pull Theme
```bash
# Pull live theme
shopify theme pull --live
# Pull specific theme
shopify theme pull --theme=123456789
# Pull only templates
shopify theme pull --only=templates
```
### Push Theme
```bash
# Push to development theme
shopify theme push --development
# Create new unpublished theme
shopify theme push --unpublished
# Push specific files
shopify theme push --only=sections,snippets
```
### Theme Check
Lint theme code:
```bash
shopify theme check
shopify theme check --auto-correct
```
## Common Patterns
### Product Form with Variants
```liquid
{% form 'product', product %}
{% unless product.has_only_default_variant %}
{% for option in product.options_with_values %}
{% for value in option.values %}
{{ value }}
{% endfor %}
{% endfor %}
{% endunless %}
{% endform %}
```
### Pagination
```liquid
{% paginate collection.products by 12 %}
{% for product in collection.products %}
{% render 'product-card', product: product %}
{% endfor %}
{% if paginate.pages > 1 %}
{% if paginate.previous %}
Previous
{% endif %}
{% for part in paginate.parts %}
{% if part.is_link %}
{{ part.title }}
{% else %}
{{ part.title }}
{% endif %}
{% endfor %}
{% if paginate.next %}
Next
{% endif %}
{% endif %}
{% endpaginate %}
```
### Cart AJAX
```javascript
// Add to cart
fetch('/cart/add.js', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
id: variantId,
quantity: 1
})
})
.then(res => res.json())
.then(item => console.log('Added:', item));
// Get cart
fetch('/cart.js')
.then(res => res.json())
.then(cart => console.log('Cart:', cart));
// Update cart
fetch('/cart/change.js', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
id: lineItemKey,
quantity: 2
})
})
.then(res => res.json());
```
## Metafields in Themes
Access custom data:
```liquid
{{ product.metafields.custom.care_instructions }}
{{ product.metafields.custom.material.value }}
{% if product.metafields.custom.featured %}
Featured
{% endif %}
```
## Best Practices
**Performance:**
- Optimize images (use appropriate sizes)
- Minimize Liquid logic complexity
- Use lazy loading for images
- Defer non-critical JavaScript
**Accessibility:**
- Use semantic HTML
- Include alt text for images
- Support keyboard navigation
- Ensure sufficient color contrast
**SEO:**
- Use descriptive page titles
- Include meta descriptions
- Structure content with headings
- Implement schema markup
**Code Quality:**
- Follow Shopify theme guidelines
- Use consistent naming conventions
- Comment complex logic
- Keep sections focused and reusable
## Resources
- Theme Development: https://shopify.dev/docs/themes
- Liquid Reference: https://shopify.dev/docs/api/liquid
- Dawn Theme: https://github.com/Shopify/dawn
- Theme Check: https://shopify.dev/docs/themes/tools/theme-check
Source: claude-code-templates (MIT). See About Us for full credits.