Knowledge Hub
How to use these examples
Each example shows the Liquid pattern, the schema shape, and when to use Flat settings vs blocks. Adapt class names to your theme. For full HTML-to-section conversion, use /converter or read /convert-hero-section-html-to-liquid and related component guides.
Hero section example
Heroes are single-instance layouts—use section.settings for heading, subheading, CTA, and background image. Flat export mode in the converter handles this pattern automatically.
Hero Liquid
<div class="hero">
<h1>{{ section.settings.heading }}</h1>
<p>{{ section.settings.subheading }}</p>
<a href="{{ section.settings.button_link }}">
{{ section.settings.button_label }}
</a>
</div>FAQ accordion example
FAQ rows are classic block content—each question and answer is a block merchants reorder. Use details/summary for accessible accordions.
FAQ block loop
{% for block in section.blocks %}
<details {{ block.shopify_attributes }}>
<summary>{{ block.settings.question }}</summary>
<div>{{ block.settings.answer }}</div>
</details>
{% endfor %}Collection and product grid examples
Product grids wire to Shopify collection objects. Assign the collection from settings, loop products, and render cards with live price and image data.
Featured collection loop
{% assign col = section.settings.collection %}
{% for product in col.products limit: section.settings.limit %}
<a href="{{ product.url }}">
{{ product.featured_image | image_url: width: 600 | image_tag }}
<span>{{ product.title }}</span>
<span>{{ product.price | money }}</span>
</a>
{% endfor %}Tabs example
Tab panels map to blocks with label and richtext content settings. Section-level settings control tab style. See /convert-tabs-html-to-liquid for conversion workflow.
Tab block loop
{% for block in section.blocks %}
<button>{{ block.settings.label }}</button>
<div>{{ block.settings.content }}</div>
{% endfor %}Accordion example
Accordions extend the FAQ pattern with richer richtext bodies and optional icons per row. Product detail pages use accordion_item blocks for materials, sizing, and care instructions.
Accordion block
{% for block in section.blocks %}
<details class="accordion__item" {{ block.shopify_attributes }}>
<summary>{{ block.settings.title }}</summary>
<div class="accordion__body">{{ block.settings.content }}</div>
</details>
{% endfor %}Banner and announcement examples
Promo banners typically use Flat settings—text, url, and color fields. No block loop required. Convert from HTML with /convert-banner-html-to-liquid.
Announcement bar
<div class="announcement">
<p>{{ section.settings.text }}</p>
<a href="{{ section.settings.link }}">{{ section.settings.link_label }}</a>
</div>From examples to production sections
- Paste your HTML variant into /converter to generate schema automatically.
- Cross-check setting ids against /shopify-schema-guide conventions.
- Validate block limits and presets before client handoff.
- Browse /shopify-cheat-sheet for filter and tag reference.
Choosing Flat versus Block export for each pattern
Flat mode fits single-layout components: one hero, one promo strip, one image-with-text band. Block mode fits any HTML where siblings repeat with the same structure—FAQ rows, slides, logo grids, feature columns. Mixed layouts need judgment: a testimonial section with one quoted sentence is Flat; six testimonial cards is Block. When the converter suggests blocks on a hero because the mockup included three decorative icon spans, override to Flat and move icons to section settings or SVG assets. Wrong mode produces either unmaintainable setting lists (heading_7, heading_8) or blocks merchants cannot reorder when they should.
Product grids are neither pure Flat nor classic blocks—they use section.settings for collection and limit, then loop collection.products. Treat that as a third pattern family: catalog loops. Tabs and accordions are block families with extra JavaScript in the theme. Label pattern families in your internal tickets so reviewers know which example on this page is the acceptance reference.
Accessibility notes for example markup
FAQ examples using details and summary provide keyboard-friendly disclosure without custom JS on many browsers—keep summary text concise and ensure answer content is reachable when expanded. Hero examples should use a single h1 per page context; if the theme already outputs h1 from another section, downgrade example heading tags to h2 in production. Tab examples need aria-selected and panel roles when JavaScript drives activation— the minimal loop on this page is structural, not a complete accessible widget. Image examples should pull alt text from image.alt or explicit alt settings, not leave alt attributes empty on decorative and informative images alike.
Liquid examples: where to start if you are new
A Shopify Liquid example is not a finished section file—it is a minimal pattern that shows how markup, store data, and merchant settings connect. Every example on this page answers one question: given a common UI component (hero, FAQ row, product card), what does the Liquid look like when the content is editable? Static HTML hardcodes copy and image URLs. Liquid replaces those literals with section.settings for fixed fields or block.settings inside a {% for block in section.blocks %} loop for repeatable rows. Store objects—product, collection, cart—supply live catalog data your HTML mockup faked with placeholder text. Before copying any snippet, identify which strings in your design are merchant-owned, which rows repeat, and which values must come from Shopify at render time. If you cannot label each visible element with one of those three sources, the pattern is incomplete. Read /shopify-liquid-for-beginners first if output tags and for loops are still unfamiliar; return here when you need shape, not theory.
From design HTML to an example pattern
Static HTML (Figma export)
│
├─ single headline? → section.settings.heading
├─ repeating cards? → section.blocks + block.settings
└─ live product data? → product / collection objects
│
▼
Example Liquid + schema skeleton
│
▼
Full section.liquid in your themeExamples sit in the middle of the pipeline—they teach the mapping before you ship a preset and JSON template entry.
How developers actually use these examples on client work
- 01
Match the mockup to a pattern family
Scan the HTML for repeatability. One headline and one CTA is a hero (Flat settings). Six identical FAQ rows is a block loop. A collection grid needs a collection picker plus a product loop. Naming the family early prevents choosing the wrong export mode in /converter.
- 02
Paste HTML into /converter for a first pass
The tool generates setting ids, block types, and scoped CSS from your DOM. Compare its output to the relevant example here—hero Liquid should resemble the hero example; gaps tell you what to fix manually.
- 03
Align schema with /shopify-schema-guide conventions
Rename vague ids (text_1, heading_2) to merchant language (promo_heading, cta_label). Add defaults that mirror approved copy so the editor preview is not empty on first insert.
- 04
Extract repeats into snippets when the loop is structural
Product cards inside a collection grid should render via {% render 'card-product', product: product %}—the example shows inline markup; production themes almost always snippetize cards shared across templates.
- 05
Register the section and QA in the theme editor
Follow /shopify-section-tutorial for JSON template steps. Add two extra blocks on FAQ examples, clear optional images on heroes, and confirm blank states do not output empty heading tags.
Common mistakes when copying Liquid examples
- Pasting examples without {% schema %}—merchants cannot edit fields; the section is dead on arrival.
- Using block.settings outside a block loop—Liquid returns nil and the storefront shows blank rows.
- Hardcoding /collections/all or product URLs from the mockup instead of {{ product.url }} or routes.
- Omitting block.shopify_attributes on FAQ, tab, and accordion wrappers—editor selection breaks even when HTML looks correct.
- Looping all collection.products without limit—performance tanks on large catalogs; mirror section.settings.products_to_show from the example.
- Copying featured_image filters on themes that standardize featured_media—video products render wrong.
- Skipping blank checks—{% if section.settings.heading != blank %} prevents empty accessibility landmarks.
- Dropping scoped CSS—examples omit theme-specific prefixes; your section needs #shopify-section-{{ section.id }} or a BEM root class.
Best practices for example-driven section builds
Treat each example as a contract template. Hero examples use Flat section settings because the layout is single-instance—do not add blocks just because blocks feel more advanced. FAQ and accordion examples use blocks because row count varies by merchant. Product grid examples wire collection from a picker setting, not a hardcoded handle, so merchandising can change without deploys. Keep one concern per example file in your internal repo: promo-hero.liquid, faq-accordion.liquid, featured-collection-row.liquid. Prefix setting ids when a section grows—hero_heading versus footer_heading. Ship at least one preset per section with realistic defaults. Document which /shopify-cheat-sheet filters the example relies on (money, image_url, default) so juniors know what to look up. When an example diverges from Dawn patterns, note why in a one-line comment above the schema block—future you will forget the client-specific reason.
Hero: HTML source, Liquid output, and schema skeleton
The hero example above is intentionally minimal. Production heroes add overlay opacity, mobile image fallbacks, and link_url validation. Start from static HTML like the structure below, then map each text node and image src to a setting id.
Static hero HTML (design handoff)
<section class="promo-hero"> <img src="hero.jpg" alt="Summer collection" /> <h1>Summer collection is live</h1> <p>Free shipping on orders over $50</p> <a href="/collections/summer">Shop now</a> </section>
Every text node and the image become schema settings—not literal strings in Liquid.
Hero Liquid with blank guards
{%- if section.settings.image != blank -%}
{{ section.settings.image | image_url: width: 1600 | image_tag:
loading: 'eager',
alt: section.settings.image.alt | default: section.settings.heading
}}
{%- endif -%}
{%- if section.settings.heading != blank -%}
<h1>{{ section.settings.heading }}</h1>
{%- endif -%}
{%- if section.settings.subheading != blank -%}
<p>{{ section.settings.subheading }}</p>
{%- endif -%}
{%- if section.settings.button_label != blank and section.settings.button_link != blank -%}
<a href="{{ section.settings.button_link }}">{{ section.settings.button_label }}</a>
{%- endif -%}Trimmed tags and blank checks keep hero markup tight when optional fields are empty.
Hero schema excerpt
{
"name": "Promo hero",
"settings": [
{ "type": "image_picker", "id": "image", "label": "Background image" },
{ "type": "text", "id": "heading", "label": "Heading", "default": "Summer collection is live" },
{ "type": "text", "id": "subheading", "label": "Subheading" },
{ "type": "text", "id": "button_label", "label": "Button label", "default": "Shop now" },
{ "type": "url", "id": "button_link", "label": "Button link" }
],
"presets": [{ "name": "Promo hero" }]
}Defaults mirror design copy so merchants see a complete hero on first insert.
FAQ block: accessible details/summary pattern
FAQ block schema + Liquid
{% for block in section.blocks %}
<details class="faq__item" {{ block.shopify_attributes }}>
<summary>{{ block.settings.question }}</summary>
<div class="faq__answer rte">{{ block.settings.answer }}</div>
</details>
{% else %}
<p class="faq__empty">Add FAQ items in the theme editor.</p>
{% endfor %}
// schema blocks entry:
{
"type": "faq_item",
"name": "FAQ item",
"settings": [
{ "type": "text", "id": "question", "label": "Question" },
{ "type": "richtext", "id": "answer", "label": "Answer" }
]
}details/summary gives keyboard-accessible accordions without custom JS on many storefronts.
Collection grid: wiring live catalog data
Featured collection loop
{%- assign col = section.settings.collection -%}
{%- if col != blank and col.products_count > 0 -%}
<ul class="product-grid">
{%- for product in col.products limit: section.settings.limit -%}
<li>
<a href="{{ product.url }}">
{%- if product.featured_media -%}
{{ product.featured_media | image_url: width: 600 | image_tag: loading: 'lazy' }}
{%- endif -%}
<span>{{ product.title }}</span>
<span>{{ product.price | money }}</span>
</a>
</li>
{%- endfor -%}
</ul>
{%- endif -%}Assign the collection once; limit the loop; use featured_media for video-capable catalogs.
Announcement bar: Flat settings only
Announcement Liquid
{%- if section.settings.text != blank -%}
<div class="announcement" role="region" aria-label="Announcement">
<p>{{ section.settings.text | escape }}</p>
{%- if section.settings.link != blank and section.settings.link_label != blank -%}
<a href="{{ section.settings.link }}">{{ section.settings.link_label | escape }}</a>
{%- endif -%}
</div>
{%- endif -%}Single-row promos rarely need blocks—escape user-facing strings when the setting is plain text.
Tabs: separating labels from panel content
Tab UIs confuse beginners because both the tab list and panel body appear in one HTML file. In Liquid, each tab panel is typically one block with label (text) and content (richtext) settings. Section-level settings control visual style—underline versus pill tabs—not individual tab copy. JavaScript in the theme reads block order to wire click handlers; Liquid only outputs data attributes and accessible roles. When converting tab HTML from /converter, verify navigation items were not exported as blocks while panel bodies were missed—split DOM structures cause lopsided schema. Cross-link merchants to /dynamic-shopify-blocks-guide when they need to add a fourth policy tab without a deploy.
Building an internal example library
Agencies that ship ten or more storefronts per year maintain a private example repo tagged by pattern, not by client. Tag hero_flat, faq_blocks, collection_grid, and tabs_blocks. When a ticket arrives, search the tag, copy the section skeleton, and replace schema defaults with client copy. Public examples on this page stay generic on purpose—they omit brand fonts and color_scheme tokens tied to one theme. Your internal fork should document which parent theme each example was last validated against—Dawn 15 behavior differs from Dawn 11 in image_tag defaults. During code review, ask: does this PR introduce a new pattern? If yes, add or update an example entry so the next developer does not rediscover the same mapping. Example libraries decay when nobody updates them after Shopify deprecates a filter; schedule a quarterly thirty-minute review against /shopify-cheat-sheet release notes.
Performance, editor usability, and long-term maintenance
Examples trade completeness for clarity—production sections must add limits and lazy loading. Collection grids should cap products_to_show between four and twelve on homepages unless the design system proves otherwise. Hero images above the fold use loading eager; everything in grids uses lazy. Keep schema setting counts under twenty per section where possible; merchants scroll endlessly when every padding edge has its own range slider. Group advanced controls under header settings in schema so the sidebar stays scannable—see /shopify-schema-guide for header and paragraph types. Scoped CSS prevents one example's grid rules from collapsing another section's card layout. When the same card markup appears in three examples, promote it to a snippet once; maintenance happens in one file instead of three. Theme editor usability improves when examples become presets with names merchants recognize—Summer promo hero, not Custom section 4.
- Rendering: limit loops; avoid nested product loops inside collection tabs without pagination.
- Maintainability: one snippet per card/row pattern; examples document the snippet contract.
- Editor UX: defaults on every visible field; presets with two or more blocks on FAQ examples.
- Schema organization: section settings for module chrome; blocks for variable rows only.
Practical summary
Use this page as a pattern library, not a copy-paste theme pack. Match your HTML to the closest example, generate a fuller section with /converter, refine schema ids against /shopify-schema-guide, and register the file using /shopify-section-tutorial. Keep /shopify-cheat-sheet open for filter syntax when examples reference money, image_url, or default. The goal is repeatable mapping from design HTML to merchant-editable Liquid—once the mapping is muscle memory, examples become verification rather than crutches. Ship presets, guard blanks, scope CSS, and snippetize anything repeated twice.
When onboarding a junior developer, assign one example family per week—hero Flat settings week one, FAQ blocks week two, collection loops week three. Have them explain aloud which visible strings map to section.settings, block.settings, or Shopify objects before writing Liquid. That narration catches hardcoded copy faster than lint rules. Senior reviewers should compare converter output against these examples line by line on the first PR for each pattern family. Divergence is fine when documented; silent divergence becomes tech debt across client themes.

