Skip to content

Snippets

Snippets are reusable Liquid partials that can be included in layouts, templates, or other snippets. They help you keep your code DRY (Don't Repeat Yourself) and make your theme easier to maintain.

Creating Snippets

Snippets live in the snippets/ directory and are included using the {% include %} tag:

liquid
{% include 'product-card' %}
{% include 'navigation' %}
{% include 'footer' %}

Basic Snippet

Create snippets/product-card.liquid:

liquid
<div class="product-card">
  <a href="{{ product.url }}">
    <img src="{{ product.images.first.url | filter, width: '300px' }}" alt="{{ product.name }}">
    <h3>{{ product.name }}</h3>
    <p class="price">{{ product.price | money_with_currency }}</p>
  </a>
</div>

Use it in a template:

liquid
<div class="product-grid">
  {% for product in products.featured %}
    {% include 'product-card' %}
  {% endfor %}
</div>

Passing Variables to Snippets

Direct Assignment

Pass variables explicitly:

liquid
{% include 'product-card', product: featured_product, show_badge: true %}

In snippets/product-card.liquid:

liquid
<div class="product-card">
  {% if show_badge %}
    <span class="badge">Featured</span>
  {% endif %}

  <a href="{{ product.url }}">
    <img src="{{ product.images.first.url | filter, width: '300px' }}" alt="{{ product.name }}">
    <h3>{{ product.name }}</h3>
    <p>{{ product.price | money_with_currency }}</p>
  </a>
</div>

Multiple Parameters

liquid
{% include 'section-header',
  title: 'Featured Products',
  subtitle: 'Our best sellers',
  alignment: 'center' %}

In snippets/section-header.liquid:

liquid
<header class="section-header text-{{ alignment | default: 'left' }}">
  <h2>{{ title }}</h2>
  {% if subtitle %}
    <p class="subtitle">{{ subtitle }}</p>
  {% endif %}
</header>

Real-World Snippet Examples

snippets/navigation.liquid:

liquid
<header class="main-header">
  <div class="container">
    <a href="{% if locale_url_prefix %}{{ locale_url_prefix }}{% else %}/{% endif %}" class="logo">
      <img src="{{ 'logo.png' | theme_image_url }}" alt="{{ site.name }}">
    </a>

    <nav class="main-nav">
      {% nav main, class: "menu", link_class: "menu-link" %}
    </nav>

    <!-- Language Switcher -->
    {% assign translation_count = page.translations | size %}
    {% if translation_count > 1 %}
      <div class="language-switcher">
        {% for translation in page.translations %}
          <a href="{% localized_path translation.locale %}"
             class="{% if locale == translation.locale %}active{% endif %}">
            {{ translation.locale | upcase }}
          </a>
        {% endfor %}
      </div>
    {% endif %}

    <!-- Mobile Menu Toggle -->
    <button class="menu-toggle" aria-label="Toggle menu">
      <span></span>
      <span></span>
      <span></span>
    </button>
  </div>
</header>

Product Card with Variants

snippets/product-card.liquid:

liquid
<div class="product-card" data-product-id="{{ product.id }}">
  <a href="{{ product.url }}" class="product-image">
    {% if product.images.first %}
      <img src="{{ product.images.first.url | filter, width: '400px', cropping: 'fill' }}"
           alt="{{ product.name }}">
    {% else %}
      <img src="{{ 'placeholder-product.png' | theme_image_url }}" alt="{{ product.name }}">
    {% endif %}

    {% if product.on_sale %}
      <span class="badge badge-sale">Sale</span>
    {% endif %}
  </a>

  <div class="product-info">
    <h3><a href="{{ product.url }}">{{ product.name }}</a></h3>

    <div class="product-price">
      {% if product.on_sale %}
        <span class="sale-price">{{ product.on_sale_price | money_with_currency }}</span>
        <span class="original-price">{{ product.price | money_with_currency }}</span>
        <span class="save-amount">
          Save {{ product.price | minus: product.on_sale_price | money_with_currency }}
        </span>
      {% else %}
        <span class="price">{{ product.price | money_with_currency }}</span>
      {% endif %}
    </div>

    {% if show_variants and product.variants.size > 1 %}
      <div class="product-variants">
        {% for variant in product.variants limit: 5 %}
          <span class="variant-option">{{ variant.name }}</span>
        {% endfor %}
        {% if product.variants.size > 5 %}
          <span class="more-variants">+{{ product.variants.size | minus: 5 }} more</span>
        {% endif %}
      </div>
    {% endif %}

    <a href="{{ product.url }}" class="btn btn-outline">View Details</a>
  </div>
</div>

Blog Article Card

snippets/article-card.liquid:

liquid
<article class="article-card">
  {% if article.thumbnail.url %}
    <a href="{{ article.url }}" class="article-image">
      <img src="{{ article.thumbnail.url | filter, width: '600px', height: '400px', cropping: 'fill' }}"
           alt="{{ article.title }}">
    </a>
  {% endif %}

  <div class="article-content">
    <div class="article-meta">
      <span class="date">{{ article.published_at | localized_date: 'short' }}</span>
      {% if article.author %}
        <span class="author">by {{ article.author }}</span>
      {% endif %}
    </div>

    <h3><a href="{{ article.url }}">{{ article.title }}</a></h3>

    <p class="excerpt">{{ article.excerpt | truncatewords: 30 }}</p>

    <a href="{{ article.url }}" class="read-more">
      {% translate 'blog.read_more', default: 'Read More' %} →
    </a>
  </div>
</article>

Snippets for Repeatable Content

Text & Image Block

snippets/repeatables/text-image.liquid:

liquid
<section class="text-image-section">
  <div class="container">
    <div class="row align-items-center">
      <div class="col-md-6 {% if image_position == 'right' %}order-md-2{% endif %}">
        <div class="image-wrapper">
          {% editable_file image %}
            {{ "placeholder-image.jpg" | theme_image_url }}
          {% endeditable_file %}
        </div>
      </div>

      <div class="col-md-6">
        <div class="text-wrapper">
          {% editable_field heading %}Heading Goes Here{% endeditable_field %}

          {% editable_text content %}
            <p>Add your content here...</p>
          {% endeditable_text %}

          {% editable_field button_text, assign: btn_text %}
          {% editable_field button_link, assign: btn_link %}

          {% if btn_link and btn_text %}
            <a href="{{ btn_link }}" class="btn btn-primary">{{ btn_text }}</a>
          {% endif %}
        </div>
      </div>
    </div>
  </div>
</section>

<!-- Snippet Settings -->
{% editable_group settings, label: "Section Settings" %}
  {% editable_select image_position, options: "left,right", labels: "Left,Right", assign: image_position %}
  {% editable_select background_color, options: "white,gray,dark", labels: "White,Gray,Dark" %}
{% endeditable_group %}

Card Grid

snippets/repeatables/cards.liquid:

liquid
<section class="cards-section">
  <div class="container">
    {% editable_field section_title, assign: title %}
    {% if title %}
      <h2 class="section-title">{{ title }}</h2>
    {% endif %}

    <div class="cards-grid">
      {% editable_canvas cards %}
        {% repeatable "Card" %}
          <div class="card">
            <div class="card-icon">
              {% editable_file icon %}
                {{ "icon-placeholder.svg" | theme_image_url }}
              {% endeditable_file %}
            </div>

            <h3 class="card-title">
              {% editable_field title %}Card Title{% endeditable_field %}
            </h3>

            <div class="card-text">
              {% editable_text description %}
                <p>Card description goes here.</p>
              {% endeditable_text %}
            </div>
          </div>
        {% endrepeatable %}
      {% endeditable_canvas %}
    </div>
  </div>
</section>

Hero Section

snippets/repeatables/hero.liquid:

liquid
<section class="hero-section" style="background-image: url('{{ background_image }}');">
  <div class="hero-overlay"></div>

  <div class="container">
    <div class="hero-content">
      <h1>{% editable_field heading %}Hero Heading{% endeditable_field %}</h1>

      <div class="hero-text">
        {% editable_text subheading %}
          <p>Your compelling subheading goes here.</p>
        {% endeditable_text %}
      </div>

      {% editable_field button_text, assign: btn_text %}
      {% editable_field button_link, assign: btn_link %}

      {% if btn_text and btn_link %}
        <a href="{{ btn_link }}" class="btn btn-lg btn-primary">{{ btn_text }}</a>
      {% endif %}
    </div>
  </div>
</section>

<!-- Settings -->
{% editable_group settings, label: "Hero Settings" %}
  {% editable_file background_image, assign: background_image, label: "Background Image" %}
  {% editable_select text_alignment, options: "left,center,right", assign: text_alignment %}
  {% editable_select overlay_opacity, options: "0,0.3,0.5,0.7", labels: "None,Light,Medium,Dark" %}
{% endeditable_group %}

Utility Snippets

Social Sharing

snippets/social-share.liquid:

liquid
<div class="social-share">
  <span class="share-label">{% translate 'share.label', default: 'Share:' %}</span>

  <a href="https://www.facebook.com/sharer/sharer.php?u={{ url.current | url_encode }}"
     target="_blank" rel="noopener" class="share-link facebook">
    <i class="fab fa-facebook-f"></i>
  </a>

  <a href="https://twitter.com/intent/tweet?url={{ url.current | url_encode }}&text={{ share_title | url_encode }}"
     target="_blank" rel="noopener" class="share-link twitter">
    <i class="fab fa-twitter"></i>
  </a>

  <a href="https://www.linkedin.com/sharing/share-offsite/?url={{ url.current | url_encode }}"
     target="_blank" rel="noopener" class="share-link linkedin">
    <i class="fab fa-linkedin-in"></i>
  </a>

  <a href="mailto:?subject={{ share_title | url_encode }}&body={{ url.current | url_encode }}"
     class="share-link email">
    <i class="fas fa-envelope"></i>
  </a>
</div>

Pagination

snippets/custom-pagination.liquid:

liquid
{% if paginate.pages > 1 %}
  <nav class="pagination" aria-label="Pagination">
    {% if paginate.previous %}
      <a href="{{ paginate.previous.url }}" class="pagination-prev">
        ← {% translate 'pagination.previous', default: 'Previous' %}
      </a>
    {% endif %}

    <ul class="pagination-numbers">
      {% for part in paginate.parts %}
        {% if part.is_link %}
          <li><a href="{{ part.url }}">{{ part.title }}</a></li>
        {% elsif part.title == paginate.current_page %}
          <li class="active"><span>{{ part.title }}</span></li>
        {% else %}
          <li><span>{{ part.title }}</span></li>
        {% endif %}
      {% endfor %}
    </ul>

    {% if paginate.next %}
      <a href="{{ paginate.next.url }}" class="pagination-next">
        {% translate 'pagination.next', default: 'Next' %} →
      </a>
    {% endif %}
  </nav>
{% endif %}

Conditional Snippets

Load different snippets based on conditions:

liquid
{% if template == 'product' %}
  {% include 'product-schema-org' %}
{% elsif template == 'article' %}
  {% include 'article-schema-org' %}
{% endif %}

{% case product.type %}
  {% when 'Clothing' %}
    {% include 'product-size-guide' %}
  {% when 'Electronics' %}
    {% include 'product-specifications' %}
{% endcase %}

Snippet Organization

Organize snippets into subdirectories for better management:

snippets/
├── navigation.liquid
├── footer.liquid
├── product-card.liquid
├── article-card.liquid
├── repeatables/
│   ├── hero.liquid
│   ├── text-image.liquid
│   ├── cards.liquid
│   ├── gallery.liquid
│   └── cta.liquid
├── forms/
│   ├── contact-form.liquid
│   ├── newsletter-form.liquid
│   └── search-form.liquid
└── social/
    ├── share-buttons.liquid
    └── follow-buttons.liquid

Include with paths:

liquid
{% include 'repeatables/hero' %}
{% include 'forms/contact-form' %}
{% include 'social/share-buttons' %}

Snippet Best Practices

1. Keep Snippets Focused

Each snippet should do one thing well. Don't create massive multi-purpose snippets.

Good:

  • product-card.liquid
  • article-card.liquid
  • social-share.liquid

Bad:

  • all-cards.liquid (handles products, articles, pages, etc.)

2. Use Default Values

Provide sensible defaults for optional parameters:

liquid
<div class="text-{{ alignment | default: 'left' }}">
  {{ content | default: "Add content here" }}
</div>

3. Document Parameters

Add comments at the top of complex snippets:

liquid
{%- comment -%}
  Product Card Snippet

  Parameters:
  - product (required): Product object
  - show_badge (optional): Display sale/new badges
  - show_variants (optional): Show variant options
  - card_style (optional): 'grid' or 'list' layout

  Usage:
  {% include 'product-card', product: product, show_badge: true %}
{%- endcomment -%}

4. Handle Missing Data

Always check if required data exists:

liquid
{% if product %}
  <h3>{{ product.name }}</h3>
  <p>{{ product.price | money_with_currency }}</p>
{% else %}
  <p class="error">Product not found</p>
{% endif %}

5. Avoid Deep Nesting

Don't include snippets within snippets too deeply. It makes debugging difficult and can impact performance.

6. Use Meaningful Names

Name snippets based on what they do:

Good:

  • product-card.liquid
  • newsletter-signup.liquid
  • mobile-menu.liquid

Bad:

  • snippet1.liquid
  • temp.liquid
  • new.liquid

Performance Considerations

Cache Expensive Snippets

liquid
{% cache 'product-grid', expires_in: 3600 %}
  {% for product in products.all %}
    {% include 'product-card', product: product %}
  {% endfor %}
{% endcache %}

Lazy Load Images in Snippets

liquid
<img src="{{ product.image.url | filter, width: '400px' }}"
     loading="lazy"
     alt="{{ product.name }}">

Minimize Snippet Calls in Loops

liquid
<!-- Less efficient -->
{% for product in products %}
  {% include 'product-card-header' %}
  {% include 'product-card-body' %}
  {% include 'product-card-footer' %}
{% endfor %}

<!-- More efficient -->
{% for product in products %}
  {% include 'product-card' %}
{% endfor %}

Next Steps

Continue to Editables to learn how to make your snippets editable.