Key takeaways
- A new section type is a Liquid file in
sections/with an HTML structure, a{% schema %}block, and presets to appear in the “Add section” menu.- This guide builds a complete testimonials section with editable heading, column count, and repeating testimonial blocks (quote, author, rating).
"max_blocks"limits how many blocks merchants can add."min_blocks"requires a minimum.- Once published, the section appears in the Theme Editor for any page that allows sections.
A new section type becomes part of your theme’s section library — available to add to any page template that supports sections. This guide walks through building a complete, production-ready testimonials section from nothing.
How do I add a new section in Shopify?
Create a new .liquid file in your theme’s sections/ folder. Give it a descriptive kebab-case name (e.g., testimonials-grid.liquid). The file must include a valid {% schema %} block with a "presets" key for it to appear in the “Add section” menu.
Related: Add Custom Liquid Logic in Shopify.
Planning the section
Before writing code, define what the section needs:
Related: Fudge Page Builder.
Section-level settings (global):
- Heading text
- Subheading text
- Number of columns on desktop (2 or 3)
Block-level settings (per testimonial):
- Quote (the testimonial text)
- Author name
- Author title/role
- Star rating (1-5)
- Author photo (optional)
Behavior:
- Maximum 12 testimonials
- Minimum 1 testimonial
- Default preset includes 3 sample testimonials
Step 1 — Create the section file
Open the code editor → sections/ folder → add new file: testimonials-grid.liquid.
Step 2 — Write the HTML structure
<section class="testimonials-grid section-{{ section.id }}" id="section-{{ section.id }}">
<div class="page-width">
{% if section.settings.heading != blank %}
<h2 class="testimonials-grid__heading">{{ section.settings.heading }}</h2>
{% endif %}
{% if section.settings.subheading != blank %}
<p class="testimonials-grid__subheading">{{ section.settings.subheading }}</p>
{% endif %}
<div class="testimonials-grid__grid testimonials-grid__grid--{{ section.settings.columns }}-col">
{% for block in section.blocks %}
<div class="testimonials-grid__item" {{ block.shopify_attributes }}>
{% if block.settings.rating > 0 %}
<div class="testimonials-grid__stars" aria-label="{{ block.settings.rating }} out of 5 stars">
{% for i in (1..5) %}
<span class="testimonials-grid__star {% if i <= block.settings.rating %}testimonials-grid__star--filled{% endif %}">★</span>
{% endfor %}
</div>
{% endif %}
{% if block.settings.quote != blank %}
<blockquote class="testimonials-grid__quote">
{{ block.settings.quote }}
</blockquote>
{% endif %}
<div class="testimonials-grid__author">
{% if block.settings.author_photo != blank %}
<img
src="{{ block.settings.author_photo | img_url: '80x80', crop: 'center' }}"
alt="{{ block.settings.author_name }}"
class="testimonials-grid__author-photo"
loading="lazy"
width="40"
height="40"
/>
{% endif %}
<div>
{% if block.settings.author_name != blank %}
<p class="testimonials-grid__author-name">{{ block.settings.author_name }}</p>
{% endif %}
{% if block.settings.author_title != blank %}
<p class="testimonials-grid__author-title">{{ block.settings.author_title }}</p>
{% endif %}
</div>
</div>
</div>
{% endfor %}
</div>
</div>
</section>
Step 3 — Write the schema
{% schema %}
{
"name": "Testimonials Grid",
"tag": "section",
"class": "section",
"settings": [
{
"type": "text",
"id": "heading",
"label": "Heading",
"default": "What our customers say"
},
{
"type": "text",
"id": "subheading",
"label": "Subheading",
"default": "Trusted by thousands of happy customers"
},
{
"type": "select",
"id": "columns",
"label": "Columns on desktop",
"options": [
{ "value": "2", "label": "2 columns" },
{ "value": "3", "label": "3 columns" }
],
"default": "3"
}
],
"blocks": [
{
"type": "testimonial",
"name": "Testimonial",
"settings": [
{
"type": "range",
"id": "rating",
"label": "Star rating",
"min": 1,
"max": 5,
"step": 1,
"default": 5
},
{
"type": "textarea",
"id": "quote",
"label": "Quote",
"default": "This product completely changed the way I work. Couldn't be happier."
},
{
"type": "image_picker",
"id": "author_photo",
"label": "Author photo"
},
{
"type": "text",
"id": "author_name",
"label": "Author name",
"default": "Jane Smith"
},
{
"type": "text",
"id": "author_title",
"label": "Author title or company",
"default": "Verified Customer"
}
]
}
],
"max_blocks": 12,
"presets": [
{
"name": "Testimonials Grid",
"blocks": [
{ "type": "testimonial" },
{ "type": "testimonial" },
{ "type": "testimonial" }
]
}
]
}
{% endschema %}
Step 4 — Add CSS
{% stylesheet %}
.testimonials-grid {
padding: 60px 0;
}
.testimonials-grid__heading {
text-align: center;
margin-bottom: 8px;
}
.testimonials-grid__subheading {
text-align: center;
color: #666;
margin-bottom: 40px;
}
.testimonials-grid__grid {
display: grid;
gap: 24px;
}
.testimonials-grid__grid--2-col {
grid-template-columns: repeat(2, 1fr);
}
.testimonials-grid__grid--3-col {
grid-template-columns: repeat(3, 1fr);
}
@media (max-width: 767px) {
.testimonials-grid__grid--2-col,
.testimonials-grid__grid--3-col {
grid-template-columns: 1fr;
}
}
.testimonials-grid__item {
background: #f9f9f9;
padding: 24px;
border-radius: 8px;
}
.testimonials-grid__star--filled {
color: #f5a623;
}
.testimonials-grid__quote {
font-style: italic;
margin: 12px 0 16px;
}
.testimonials-grid__author {
display: flex;
align-items: center;
gap: 12px;
}
.testimonials-grid__author-photo {
width: 40px;
height: 40px;
border-radius: 50%;
object-fit: cover;
}
.testimonials-grid__author-name {
font-weight: bold;
margin: 0;
}
.testimonials-grid__author-title {
font-size: 14px;
color: #666;
margin: 0;
}
{% endstylesheet %}
Step 5 — Test
After saving, go to Online Store → Themes → Customize. Click “Add section” in any page. Your “Testimonials Grid” section should appear in the list. Add it and confirm the settings panel works correctly.
How do I add a new type in Shopify?
“Type” in the context of sections refers to block types within a section (like the "type": "testimonial" block above) or the section type itself. You add new section types by creating new Liquid files in sections/. You add new block types by adding entries to a section’s "blocks" array in its schema.
FAQ
The single most common cause: missing "presets" array in the schema. A section without presets is technically valid Liquid but Shopify won't list it in the "Add section" dropdown — add at least one preset entry with a "name" and you should see it appear. (If you'd rather skip writing schema by hand, Fudge generates the section file with valid presets, schema, and Liquid from a plain English description.)
Section settings apply once to the whole section (the heading, the column count, the background colour). Block settings apply per repeated child item inside the section (each testimonial's quote, author, rating). Use section settings for global config, blocks for repeating content the merchant adds and reorders.
Yes - in the schema, add "enabled_on": { "templates": ["product"] } to restrict it to product pages only, or "disabled_on": { "templates": ["index"] } to hide it from the homepage. By default a section with presets is available on every JSON template.
You can't - they're different concepts. App blocks are extensions installed by an app and appear in the same "Add section" UI but are scoped to the app. A theme section lives in your theme code. If you're building it yourself, just make a theme section.
The Liquid is being rendered as content instead of parsed. Most likely the file is in the wrong folder (must be sections/, not snippets/ or templates/), or the schema block has a JSON syntax error that breaks Liquid parsing. Check the theme inspector for errors and validate the JSON inside {% schema %} separately.
Related: Add Custom JavaScript in Shopify.
Related: Add Homepage Sections in Shopify.