Built-in Components
Reusable UI components you can use in any section template with the render tag.
Quill ships with built-in components (partials) for common UI elements. Use them with the render tag to avoid writing repetitive HTML. Each component reads from your theme settings by default, so buttons, headings, and badges all match your store's design without extra work.
How to use components
Call a component with render and pass the values it needs:
{% render 'q-btn', text: 'Shop now', url: '/collections/all' %}Every component guards against empty values. If text is blank, nothing renders. You never need to wrap components in {% if %} checks.
q-btn
A button or call-to-action link. Uses your theme's button colours, border radius, and hover styles.
{% render 'q-btn', text: 'Shop the collection', url: '/collections/summer', style: 'primary' %}| Parameter | Default | Description |
|---|---|---|
text | (required) | Button label. Blank produces no output. |
url | '#' | Link destination |
style | 'primary' | 'primary', 'outline', 'secondary', or 'link' |
size | '' | Empty uses theme default. 'sm' or 'lg' to override. |
bg | '' | Custom background colour. Empty uses theme colour. |
fg | '' | Custom text colour. Empty uses theme colour. |
data_el | 'cta' | The data-el attribute for CSS targeting |
class | '' | Additional CSS classes |
Style variants
{%- comment -%} Filled button (default) {%- endcomment -%}
{% render 'q-btn', text: 'Get started', style: 'primary' %}
{%- comment -%} Outlined button {%- endcomment -%}
{% render 'q-btn', text: 'Learn more', style: 'outline' %}
{%- comment -%} Text-only link {%- endcomment -%}
{% render 'q-btn', text: 'View details', style: 'link' %}Custom colours
Override the theme for a single button:
{% render 'q-btn', text: 'Limited offer', url: '/sale', bg: '#dc2626', fg: '#ffffff' %}q-heading
A heading element with responsive sizing. Reads font weight and letter spacing from your theme.
{% render 'q-heading', text: 'New arrivals', tag: 'h2', size: 'large' %}| Parameter | Default | Description |
|---|---|---|
text | (required) | Heading text. Blank produces no output. |
tag | 'h2' | HTML tag: 'h1' through 'h6' |
size | 'default' | 'default', 'large', or 'hero' |
weight | '' | Empty uses theme default |
tracking | '' | Empty uses theme default |
color | '' | Empty inherits from parent |
align | '' | 'center', 'left', or 'right'. Empty inherits. |
data_el | 'heading' | The data-el attribute for CSS targeting |
Size presets
The three sizes are responsive. On small screens they scale down automatically:
| Size | Mobile | Tablet | Desktop |
|---|---|---|---|
default | text-3xl | text-4xl | |
large | text-4xl | text-5xl | |
hero | text-5xl | text-6xl | text-7xl |
q-eyebrow
A small label above the heading. Styled in your theme's accent colour by default.
{% render 'q-eyebrow', text: 'Just launched' %}| Parameter | Default | Description |
|---|---|---|
text | (required) | Eyebrow text. Blank produces no output. |
color | '' | Empty uses theme accent colour |
data_el | 'eyebrow' | The data-el attribute for CSS targeting |
q-badge
A pill-shaped badge with an optional note beside it. Uses your theme's badge colours and border radius.
{% render 'q-badge', text: 'New', note: 'Free shipping included' %}| Parameter | Default | Description |
|---|---|---|
text | (required) | Badge label. Blank produces no output. |
note | '' | Small text beside the badge |
align | 'center' | 'center', 'left', or 'right' |
data_el | 'badge' | The data-el attribute for CSS targeting |
q-body
A rich text block for body copy. Reads font size from your theme. Supports HTML content from richtext schema fields.
{% render 'q-body', html: body %}| Parameter | Default | Description |
|---|---|---|
html | (required) | Rich text HTML. Blank produces no output. |
size | '' | Empty uses theme default. 'sm' or 'lg' to override. |
color | '' | Empty inherits from parent |
max_width | '' | Empty has no constraint. 'prose' limits to 32rem for readability. |
data_el | 'body' | The data-el attribute for CSS targeting |
Animation support
All components accept two optional animation parameters:
| Parameter | Description |
|---|---|
animate | Animation effect name (e.g. 'fade-up', 'scale-up') |
animate_delay | Delay in seconds before the animation starts (e.g. 0.2) |
When set, the component outputs data-q-animate and CSS custom properties that the storefront animation runtime picks up. See animate tag for the block-level equivalent.
{% render 'q-heading', text: 'Welcome', animate: 'fade-up' %}
{% render 'q-btn', text: 'Shop now', animate: 'fade-up', animate_delay: 0.2 %}Putting it together
A complete section using all five components:
<section class="py-16 text-center" style="background: {{ bg_color }}; color: {{ text_color }}">
<div class="max-w-3xl mx-auto px-6">
{% render 'q-badge', text: badge_text, note: badge_note %}
{% render 'q-eyebrow', text: eyebrow %}
{% render 'q-heading', text: heading, size: 'large' %}
{% render 'q-body', html: body, max_width: 'prose' %}
<div class="flex flex-wrap justify-center gap-4 mt-8">
{% render 'q-btn', text: cta_text, url: cta_url, style: 'primary' %}
{% render 'q-btn', text: cta2_text, url: cta2_url, style: 'outline' %}
</div>
</div>
</section>