Overview
Horizon follows Shopify’s theme architecture with enhanced organization and modern patterns. Understanding this structure is essential for effective theme development.
source/
├── assets/ # 100+ CSS, JS, and static files
├── blocks/ # 94 theme blocks
├── config/ # settings_schema.json and settings_data.json
├── layout/ # theme.liquid and password.liquid
├── locales/ # Translation files (en.default.json, etc.)
├── sections/ # 41 section files (.liquid and .json)
├── snippets/ # 93 reusable Liquid snippets
└── templates/ # 14 JSON template files
Sections
Sections are the primary building blocks of Shopify pages. Horizon includes 41 sections organized by purpose.
Universal Sections
_blocks.liquid - The Foundation
The _blocks.liquid section is Horizon’s most flexible container:
{% capture children %}
{% content_for 'blocks' %}
{% endcapture %}
{% render 'section' , section: section , children: children %}
{% schema %}
{
"name" : "t:names.section" ,
"class" : "section-wrapper" ,
"blocks" : [
{ "type" : "@theme" }, // Accept any theme block
{ "type" : "@app" }, // Accept app blocks
{ "type" : "_divider" } // Built-in divider
],
"settings" : [
{
"type" : "select" ,
"id" : "content_direction" ,
"options" : [
{ "value" : "column" , "label" : "t:options.vertical" },
{ "value" : "row" , "label" : "t:options.horizontal" }
]
},
{
"type" : "select" ,
"id" : "section_width" ,
"options" : [
{ "value" : "page-width" , "label" : "t:options.page" },
{ "value" : "full-width" , "label" : "t:options.full" }
]
},
{
"type" : "select" ,
"id" : "section_height" ,
"options" : [
{ "value" : "" , "label" : "t:options.auto" },
{ "value" : "small" , "label" : "t:options.small" },
{ "value" : "medium" , "label" : "t:options.medium" },
{ "value" : "large" , "label" : "t:options.large" },
{ "value" : "full-screen" , "label" : "t:options.full_screen" }
]
}
]
}
{% endschema %}
The { "type": "@theme" } block type allows any theme block to be added, making this section universally flexible.
Layout Sections
Hero Section (hero.liquid)
The hero section supports dual media (images/videos), custom layouts, and flexible content positioning: {% liquid
assign media_count = 0
assign media_1 = 'none'
assign media_2 = 'none'
if section . settings . image_1 != blank and section . settings . media_type_1 == 'image'
assign media_1 = 'image'
assign media_count = media_count | plus: 1
endif
if section . settings . video_1 != blank and section . settings . media_type_1 == 'video'
assign media_1 = 'video'
assign media_count = media_count | plus: 1
endif
%}
Key Features:
Dual media slots (desktop + mobile)
Blurred reflection effects
Custom height options
Background overlays with gradients
Carousel Section (carousel.liquid)
< div class = "section section-- {{ section . settings . section_width }} " >
{% content_for 'block' , type : 'group' , id : 'static-header' %}
{% content_for 'block' , type : '_carousel-content' , id : 'static-carousel-content' %}
</ div >
{% schema %}
{
"settings" : [
{
"type" : "range" ,
"id" : "columns" ,
"min" : 1 ,
"max" : 8 ,
"default" : 4
},
{
"type" : "select" ,
"id" : "mobile_columns" ,
"options" : [
{ "value" : "1" , "label" : "t:options.one_number" },
{ "value" : "2" , "label" : "t:options.two_number" }
]
}
]
}
{% endschema %}
Collection List (collection-list.liquid)
Features the advanced bento grid layout system for visually dynamic collection displays.
Page-Specific Sections
Product
Collection
Blog
Cart
main-product.liquid - Main product page section
featured-product.liquid - Featured product showcase
featured-product-information.liquid - Product details
main-collection.liquid - Collection page with filtering
main-collection-list.liquid - Collection list page
collection-links.liquid - Collection navigation
main-blog.liquid - Blog listing page
main-blog-post.liquid - Article page
featured-blog-posts.liquid - Blog highlights
main-cart.liquid - Shopping cart page
Uses _cart-products, _cart-summary, and _cart-title blocks
Section groups enable modular header/footer architecture:
sections/header-group.json
{
"type" : "header" ,
"name" : "t:names.header" ,
"sections" : {
"header_announcements" : {
"type" : "header-announcements" ,
"blocks" : {
"announcement" : {
"type" : "_announcement" ,
"settings" : {
"text" : "Welcome to our store" ,
"font_size" : "0.75rem"
}
}
}
},
"header_section" : {
"type" : "header" ,
"blocks" : {
"header-logo" : { "type" : "_header-logo" , "static" : true },
"header-menu" : { "type" : "_header-menu" , "static" : true }
},
"settings" : {
"logo_position" : "left" ,
"menu_position" : "left" ,
"enable_sticky_header" : "always" ,
"enable_transparent_header_home" : false
}
}
},
"order" : [ "header_announcements" , "header_section" ]
}
Theme blocks (94 total) are prefixed with _ and provide reusable components.
Block Categories
Content Blocks
_heading.liquid - Customizable headings
_content.liquid - Nested content groups
_divider.liquid - Section dividers
_inline-text.liquid - Inline typography
Media Blocks
_image.liquid - Responsive images
_media.liquid - Video/image media
_carousel-content.liquid - Carousel items
_layered-slide.liquid - Layered slideshows
Product Blocks
_product-card.liquid - Product cards
_product-card-gallery.liquid - Product images
_featured-product.liquid - Featured products
_featured-product-price.liquid - Pricing display
Navigation Blocks
_header-logo.liquid - Site logo
_header-menu.liquid - Navigation menus
_footer-social-icons.liquid - Social links
_announcement.liquid - Announcements
Block Schema Example
{% capture children %}
{% content_for 'blocks' %}
{% endcapture %}
{% render 'group' , children: children , settings: block . settings , shopify_attributes: block . shopify_attributes %}
{% schema %}
{
"name" : "t:names.content" ,
"tag" : null ,
"blocks" : [
{ "type" : "@theme" },
{ "type" : "@app" },
{ "type" : "_divider" }
],
"settings" : [
{
"type" : "select" ,
"id" : "horizontal_alignment_flex_direction_column" ,
"label" : "t:settings.alignment" ,
"options" : [
{ "value" : "flex-start" , "label" : "t:options.left" },
{ "value" : "center" , "label" : "t:options.center" },
{ "value" : "flex-end" , "label" : "t:options.right" }
]
},
{
"type" : "range" ,
"id" : "gap" ,
"label" : "t:settings.gap" ,
"min" : 0 ,
"max" : 100 ,
"default" : 24
},
{
"type" : "checkbox" ,
"id" : "inherit_color_scheme" ,
"label" : "t:settings.inherit_color_scheme" ,
"default" : true
}
]
}
{% endschema %}
The _content block is nestable - it accepts other theme blocks, enabling complex layouts through composition.
Snippets
Horizon contains 93 snippets organized by functionality.
Core Snippets
section.liquid - Universal Section Wrapper
{%- doc -%}
Renders a wrapper section
@param {section} section - The section object
@param {string} children - The children of the section
{%- enddoc -%}
< div class = "section-background color- {{ section . settings . color_scheme }} " ></ div >
< div
class = "section section-- {{ section . settings . section_width }} "
style = "
{% if section . settings . section_height == 'custom' %}
--section-min-height: {{ section . settings . section_height_custom }} svh;
{% elsif section . settings . section_height == 'full-screen' %}
--section-min-height: 100svh;
{% endif %}
"
>
< div class = "custom-section-background" >
{% render 'background-media' ,
background_media: section . settings . background_media ,
background_video: section . settings . video ,
background_image: section . settings . background_image
%}
</ div >
< div class = "border-style custom-section-content" >
{% if section . settings . toggle_overlay %}
{% render 'overlay' , settings: section . settings %}
{% endif %}
{{ children }}
</ div >
</ div >
Responsibilities:
Color scheme application
Background media rendering
Overlay effects
Height and width management
group.liquid - Block Container
{%- doc -%}
Renders block content for all blocks that extend the group block.
@param {string} children - The DOM content of the group block.
@param {object} settings - The settings of the group block.
@param {string} shopify_attributes - String with Shopify attributes.
{%- enddoc -%}
< div
class = "group-block {% if settings . inherit_color_scheme == false %} color- {{ settings . color_scheme }}{% endif %} "
style = "
{% render 'border-override', settings: settings %}
{% render 'spacing-style', settings: settings %}
"
{{ shopify_attributes }}
>
{%- if settings . link != blank - %}
< a href = " {{ settings . link }} " class = "group-block__link" ></ a >
{%- endif -%}
< div class = "group-block__media-wrapper" >
{% render 'background-media' ,
background_media: settings . background_media ,
background_video: settings . video ,
background_image: settings . background_image
%}
</ div >
{{ children }}
</ div >
bento-grid.liquid - Advanced Layout System
Renders items in a sophisticated bento box grid: snippets/bento-grid.liquid
{%- doc -%}
Takes an array of HTML strings and positions them in a bento box grid.
Bento boxes can hold up to 12 items.
@param {string[]} items - Array of HTML strings
{%- enddoc -%}
{% liquid
assign odd_item_check = items . size | modulo: 12
if odd_item_check == 1
assign first_box_size = 11
else
assign first_box_size = 12
endif
%}
{% for item in items %}
{% if forloop . first or item_modulo == 1 %}
< div class = "bento-box bento-box--items- {{ box_item_count }} " >
{% endif %}
< div class = "bento-box__item" >
{{ item }}
</ div >
{% if forloop . last or item_modulo == 0 %}
</ div >
{% endif %}
{% endfor %}
{% stylesheet %}
.bento-box {
display : grid ;
grid-template-columns : repeat ( 12 , 1 fr );
grid-template-areas :
'A A A B B B B B B C C C'
'D D D D D D E E E F F F'
'G G G H H H I I I I I I'
'J J J J K K K K L L L L' ;
}
{% endstylesheet %}
The bento grid dynamically adjusts for 1-12 items with optimized layouts.
Utility Snippets
card-gallery.liquid - Product image galleries
collection-card.liquid - Collection cards
editorial-product-grid.liquid - Editorial layouts
add-to-cart-button.liquid - Add to cart functionality
cart-products.liquid - Cart line items
cart-summary.liquid - Cart totals and checkout
cart-bubble.liquid - Cart count indicator
gift-card-recipient-form.liquid - Gift card forms
background-media.liquid - Background images/videos
border-override.liquid - Border styling
gap-style.liquid - Spacing utilities
grid-density-controls.liquid - Grid configurations
button.liquid - Button component
checkbox.liquid - Form checkboxes
divider.liquid - Visual dividers
color-schemes.liquid - Theme color schemes
Templates
Horizon uses JSON templates exclusively (14 files).
Template Structure
{
"sections" : {
"main" : {
"type" : "main-product" ,
"blocks" : {
"vendor" : { "type" : "text" },
"title" : { "type" : "title" },
"price" : { "type" : "price" },
"variant_picker" : { "type" : "variant_picker" },
"quantity_selector" : { "type" : "quantity_selector" },
"buy_buttons" : { "type" : "buy_buttons" }
},
"block_order" : [ "vendor" , "title" , "price" , "variant_picker" , "quantity_selector" , "buy_buttons" ]
}
},
"order" : [ "main" ]
}
Available Templates
404.json Error page template
article.json Blog post template
blog.json Blog listing template
cart.json Shopping cart template
collection.json Collection template
gift_card.liquid Gift card (Liquid)
index.json Homepage template
list-collections.json All collections template
page.json Default page template
page.contact.json Contact page template
password.json Password page template
product.json Product template
search.json Search results template
Only gift_card.liquid uses the Liquid format; all others are JSON for maximum flexibility.
Layout Files
theme.liquid
The main layout file provides the HTML shell:
<! doctype html >
< html lang = " {{ request . locale . iso_code }} " >
< head >
{%- render 'meta-tags' - %}
{%- render 'stylesheets' - %}
{%- render 'fonts' - %}
{%- render 'scripts' - %}
{%- render 'theme-styles-variables' - %}
{%- render 'color-schemes' - %}
{{ content_for_header }}
</ head >
< body class = "page-width- {{ settings . page_width }} " >
< div id = "header-group" >
{% sections 'header-group' %}
</ div >
< main id = "MainContent" role = "main" >
{{ content_for_layout }}
</ main >
< footer >
{% sections 'footer-group' %}
</ footer >
{% render 'search-modal' %}
{% if settings . quick_add %}
{% render 'quick-add-modal' %}
{% endif %}
</ body >
</ html >
password.liquid
Special layout for password-protected stores.
Horizon includes 100+ asset files:
base.css - Core styles, CSS custom properties
Component-specific styles in sections/snippets
Scoped styles using {% stylesheet %} tags
component.js - Base component class
events.js - Custom event system
cart-drawer.js - Cart functionality
header-drawer.js - Mobile navigation
product-gallery.js - Product image galleries
Web Components for interactive features
Font files
Placeholder images
Icons and graphics
Best Practices
Use theme blocks over custom sections
Theme blocks are more flexible and reusable. Prefer composing layouts with blocks rather than creating monolithic sections.
Leverage snippets for reusability
Extract common patterns into snippets. Use the {%- doc -%} tag to document parameters.
Follow naming conventions
Sections: descriptive names (hero.liquid, main-product.liquid)
Blocks: underscore prefix (_heading.liquid, _content.liquid)
Snippets: functionality-based names (section.liquid, bento-grid.liquid)
JSON templates provide better flexibility and enable merchants to customize layouts without code.
Next Steps
Liquid Storefronts Learn about modern Liquid features
Theme Blocks Deep dive into theme blocks
Development Guide Set up your development environment
Component Reference Browse all sections and blocks