Creating a section allows you to build reusable, configurable storefront components that can be managed from the builder UI. This tutorial demonstrates how to create a Sponsor section that supports reusable Brand blocks so non-developers can visually manage logos.
The implementation progresses from a static section to a fully dynamic section that renders block content with configurable settings such as images, alt text, and optional links. This improves flexibility while keeping the rendering logic controlled by developers.
When to Use
Use this when:
- You need reusable sections that non-developers can manage from the builder UI.
- You want dynamic content that can be reordered, added, or removed without code changes.
- You need configurable block settings such as images, text, or links.
- You want a scalable structure for future section enhancements.
Requirements
You can develop sections in two ways:
- Download the theme and edit locally in your IDE.
- Edit directly in the Web Code Editor.
Both approaches produce the same outcome. This tutorial assumes the Web Code Editor.
Key Concepts
Section Architecture
Sections consist of two files:
File | Purpose |
|---|
sections/sponsor.html
| Controls frontend rendering and layout |
sections/sponsor.json
| Defines metadata, block support, and settings |
The HTML file controls presentation and rendering.
The JSON file controls builder behavior and configuration.
Block Architecture
Blocks are reusable components placed inside sections.
File | Purpose |
|---|
blocks/brand.html
| Controls block rendering |
blocks/brand.json
| Defines block schema and settings |
Section → Block Relationship
Sections render blocks dynamically using:
BlockOrder → determines render orderrender_block → renders block HTMLBlock.Settings → passes configuration from JSON to HTML
This changes frontend rendering behavior only. No backend data is modified.
Implementation
Create a Static Section
Create the section files:
sections/sponsor.htmlsections/sponsor.json
sections/sponsor.html
{{ $section := . }}
<section
data-component-id="{{ $section.ID }}"
class="sponsor-section"
>
<div class="sponsor-container">
<h3>This is a static sponsor section</h3>
</div>
</section>
sections/sponsor.json
{
"id": "sponsor",
"type": "sponsor",
"label": "Sponsor",
"category": "Sponsor",
"name": "Sponsor",
"enabled_blocks": [],
"disabled_blocks": [],
"supported_on": [],
"disabled_on_templates": [],
"enabled_on_templates": [],
"blocks": [],
"block_order": [],
"settings": []
}
The section now renders but only developers can change its content.
Result
- The section can be added to pages.
- Content is hardcoded.
- Only developers can change what appears.
Enable Block Rendering in the Section
Update the section to iterate through blocks.
{{ $section := . }}
<section
data-component-id="{{ $section.ID }}"
class="sponsor-section"
>
<div class="sponsor-container">
{{ range $index, $blockID := $section.BlockOrder }}
{{ $block := index $.Blocks $blockID }}
<div class="sponsor-item">
{{ render_block $block }}
</div>
{{ end }}
</div>
</section>
This allows the section to render dynamic blocks assigned in the builder.
Add Section Styling
Add responsive grid styling.
<style>
[data-component-id="{{ $section.ID }}"].sponsor-section {
width: 100%;
padding: 40px 20px;
}
.sponsor-container {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 40px;
max-width: 1200px;
margin: 0 auto;
}
.sponsor-item {
flex: 0 0 calc(25% - 30px);
height: 150px;
min-width: 200px;
display: flex;
align-items: center;
justify-content: center;
}
@media (max-width: 768px) {
.sponsor-item {
flex: 0 0 calc(50% - 15px);
height: 120px;
}
}
@media (max-width: 480px) {
.sponsor-item {
flex: 0 0 100%;
}
}
</style>
Declare Allowed Blocks
Update sections/sponsor.json to allow Brand blocks.
"enabled_blocks": ["brand"],
"disabled_on_templates": ["header", "footer"]
This restricts the section to only Brand blocks.
Create the Brand Block Skeleton
Create:
blocks/brand.htmlblocks/brand.json
blocks/brand.html
<div class="brand-block">
<span>Brand Logo</span>
</div>
<style>
.brand-block {
width: 100%;
height: 100%;
background: #f3f4f6;
display: flex;
justify-content: center;
align-items: center;
border: 2px dashed #d1d5db;
}
</style>
blocks/brand.json
{
"id": "brand",
"name": "brand",
"label": "Brand",
"type": "brand",
"limit": 0,
"settings": []
}
Blocks can now be added but contain only placeholder content.
Add Image Setting to Block
Update blocks/brand.json.
"settings": [
{
"id": "image",
"type": "image",
"label": "Brand Logo",
"default": ""
}
]
Result
- The editor can now add Brand blocks
- Each block shows a placeholder
Render Image in Block HTML
{{ $props := .Block.Settings }}
{{ $image := $props.image }}
<div class="brand-block">
{{ if $image }}
<img
class="brand-image"
src="{{ image_url $image }}"
alt="Brand logo"
loading="lazy"
/>
{{ else }}
<span>Brand Logo</span>
{{ end }}
</div>
Add Alt Text Setting
Update block settings:
{
"id": "alt_text",
"type": "text",
"label": "Alt Text",
"placeholder": "Enter alt text for accessibility"
}
Update HTML:
{{ $alt := $props.alt_text }}
{{ if not $alt }}
{{ $alt = "Brand logo" }}
{{ end }}
Add Optional Link Setting
Update block settings:
{
"id": "link_url",
"type": "text",
"label": "Link URL",
"placeholder": "https://example.com"
}
Final block HTML:
{{ $props := .Block.Settings }}
{{ $image := $props.image }}
{{ $alt := $props.alt_text }}
{{ $link := $props.link_url }}
{{ if not $alt }}
{{ $alt = "Brand logo" }}
{{ end }}
<div class="brand-block">
{{ if $image }}
{{ if $link }}
<a href="{{ $link }}" target="_blank" rel="noopener noreferrer">
<img src="{{ image_url $image }}" alt="{{ $alt }}" />
</a>
{{ else }}
<img src="{{ image_url $image }}" alt="{{ $alt }}" />
{{ end }}
{{ else }}
<span>Brand Logo</span>
{{ end }}
</div>
Prepopulate Default Blocks
Update sections/sponsor.json.
"blocks": [
{ "id": "brand-1", "type": "brand", "label": "Brand 1", "settings": {} },
{ "id": "brand-2", "type": "brand", "label": "Brand 2", "settings": {} },
{ "id": "brand-3", "type": "brand", "label": "Brand 3", "settings": {} }
],
"block_order": ["brand-1", "brand-2", "brand-3"]
Final ResultYou now have:
- A Sponsor section
- Accepting Brand blocks
- Each Brand supports:
- Image
- Alt text
- Optional link
- Non-developers can:
- Add/remove brands
- Replace logos
- Reorder logos
Verify the Implementation
You should now be able to:
- Add and remove Brand blocks
- Replace logos
- Reorder logos
- Configure links and alt text
- Manage logos without developer changes
Troubleshooting
Blocks not rendering
- Ensure
enabled_blocks includes "brand".
Images not displaying
- Verify image setting is selected in builder.
Section missing in templates
- Check
disabled_on_templates configuration.
Security & Performance Considerations
- Images use
loading="lazy" for performance. - External links use
noopener noreferrer for security.
Next Steps + Production Checklist
Confirm the following before deployment:
- Section renders correctly across breakpoints.
- Default blocks appear in builder.
- Image, alt text, and link settings function correctly.
- Section is not enabled on restricted templates.
The Sponsor section is now ready for production use.