Components
Components are reusable Liquid template partials that encapsulate complex UI patterns. They’re larger than snippets and typically represent complete UI sections like headers, footers, cards, or navigation elements.
Location
Section titled “Location”Components are stored in the components/ directory:
theme/└── components/ ├── global-header.liquid ├── global-footer.liquid ├── event-item.liquid ├── post-item.liquid └── ...Using Components
Section titled “Using Components”Use the render tag to include a component:
{% render 'components/event-item' event: event %}Syntax
Section titled “Syntax”{% render 'components/[name]' %}{% render 'components/[name]' variable: value %}{% render 'components/[name]' var1: value1, var2: value2 %}Passing Variables
Section titled “Passing Variables”Components receive variables passed as named parameters:
{# In templates/page.liquid #}{% for event in upcoming_events limit: 3 %} {% render 'components/event-item' event: event %}{% endfor %}{# In components/event-item.liquid #}<article class="event-item"> <h3>{{ event.title }}</h3> <time>{{ event.startDate | date: '%B %d, %Y' }}</time></article>Multiple Variables
Section titled “Multiple Variables”{% render 'components/event-item' event: event, show_image: true, image_size: 'large'%}Component Examples
Section titled “Component Examples”Event Card Component
Section titled “Event Card Component”{# components/event-item.liquid #}<a class="event-item" href="/events/{{ event.slug }}"> <div class="event-item__media"> {% if event.image %} <img src="{{ event.image | image_url: width: 600, height: 360 }}" alt="{{ event.image.alt | default: event.title }}" class="event-item__image" loading="lazy" > {% elsif settings.global.fallbackImage %} <img src="{{ settings.global.fallbackImage | image_url: width: 600, height: 360 }}" alt="" class="event-item__image" loading="lazy" > {% endif %} </div>
<div class="event-item__content"> <h3 class="event-item__title">{{ event.title }}</h3>
{% if event.startDate %} <p class="event-item__date"> {{ event.startDate | date: '%B %d, %Y' }} {% if event.endDate and event.endDate != event.startDate %} – {{ event.endDate | date: '%B %d, %Y' }} {% endif %} </p> {% endif %}
{% if event.venue %} <p class="event-item__venue">{{ event.venue.name }}</p> {% endif %} </div></a>Usage:
<div class="event-grid"> {% for event in all_events limit: 6 %} {% render 'components/event-item' event: event %} {% endfor %}</div>Header Component
Section titled “Header Component”{# components/global-header.liquid #}<header class="site-header"> <div class="site-header__inner"> <a href="/" class="site-header__logo"> {% if settings.header.logo %} <img src="{{ settings.header.logo | image_url: width: 200 }}" alt="{{ tenant.name }}" > {% else %} {{ tenant.name }} {% endif %} </a>
<nav class="site-header__nav"> {% render 'components/global-navigation' %} </nav>
<div class="site-header__actions"> {% if settings.header.donateLink %} <a href="{{ settings.header.donateLink }}" class="btn btn--primary"> Donate </a> {% endif %} </div> </div></header>Breadcrumb Component
Section titled “Breadcrumb Component”{# components/breadcrumb.liquid #}{% if page.parent %} <nav class="breadcrumb" aria-label="Breadcrumb"> <ol class="breadcrumb__list"> <li class="breadcrumb__item"> <a href="/">Home</a> </li>
{% if page.parent.parent %} <li class="breadcrumb__item"> <a href="{{ page.parent.parent.relativePath }}"> {{ page.parent.parent.title }} </a> </li> {% endif %}
{% if page.parent %} <li class="breadcrumb__item"> <a href="{{ page.parent.relativePath }}"> {{ page.parent.title }} </a> </li> {% endif %}
<li class="breadcrumb__item" aria-current="page"> {{ page.title }} </li> </ol> </nav>{% endif %}Components vs Blocks vs Snippets
Section titled “Components vs Blocks vs Snippets”| Type | Location | Purpose | Configurable |
|---|---|---|---|
| Components | components/ | Complex, reusable UI patterns | Via passed variables |
| Blocks | blocks/ | CMS-editable content sections | Via schema settings |
| Snippets | snippets/ | Small utility partials | Via passed variables |
When to Use Components
Section titled “When to Use Components”- Headers, footers, navigation
- Card layouts (event cards, post cards, etc.)
- Complex UI that appears in multiple templates
- Patterns that need consistent markup across the site
When to Use Blocks
Section titled “When to Use Blocks”- Content sections editors can add/remove/reorder
- Sections with CMS-editable settings
- Homepage builders and flexible page layouts
When to Use Snippets
Section titled “When to Use Snippets”- Icons, SVG sprites
- Small utility functions (formatting, conditionals)
- Micro-partials used within components
Best Practices
Section titled “Best Practices”-
Consistent naming - Use descriptive, hyphenated names (
event-item,global-header) -
Document expected variables - Add comments explaining required inputs
-
Handle missing data - Use defaults and conditionals for optional values
-
Keep components focused - Each component should do one thing well
-
Use settings for customization - Access theme settings for colors, text, etc.
{# components/person-card.liquid #}{# Required: person (person object) Optional: show_bio (boolean, default: false) image_size (string: 'small' | 'medium' | 'large', default: 'medium')#}
{% assign show_bio = show_bio | default: false %}{% assign image_size = image_size | default: 'medium' %}
{% case image_size %} {% when 'small' %}{% assign img_width = 100 %} {% when 'large' %}{% assign img_width = 400 %} {% else %}{% assign img_width = 200 %}{% endcase %}
<div class="person-card person-card--{{ image_size }}"> {% if person.image %} <img src="{{ person.image | image_url: width: img_width }}" alt="{{ person.name }}"> {% endif %} <h3>{{ person.name }}</h3> {% if show_bio and person.biography_html %} <div class="person-card__bio">{{ person.biography_html }}</div> {% endif %}</div>