Skip to content

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.

Components are stored in the components/ directory:

theme/
└── components/
├── global-header.liquid
├── global-footer.liquid
├── event-item.liquid
├── post-item.liquid
└── ...

Use the render tag to include a component:

{% render 'components/event-item' event: event %}
{% render 'components/[name]' %}
{% render 'components/[name]' variable: value %}
{% render 'components/[name]' var1: value1, var2: value2 %}

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 %}
{% render 'components/event-item'
event: event,
show_image: true,
image_size: 'large'
%}
{# 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>
{# 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>
{# 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 %}
TypeLocationPurposeConfigurable
Componentscomponents/Complex, reusable UI patternsVia passed variables
Blocksblocks/CMS-editable content sectionsVia schema settings
Snippetssnippets/Small utility partialsVia passed variables
  • 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
  • Content sections editors can add/remove/reorder
  • Sections with CMS-editable settings
  • Homepage builders and flexible page layouts
  • Icons, SVG sprites
  • Small utility functions (formatting, conditionals)
  • Micro-partials used within components
  1. Consistent naming - Use descriptive, hyphenated names (event-item, global-header)

  2. Document expected variables - Add comments explaining required inputs

  3. Handle missing data - Use defaults and conditionals for optional values

  4. Keep components focused - Each component should do one thing well

  5. 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>