Collection Template Architecture
Understand how collection templates work in Shopify Online Store 2.0, including JSON template structure, section organization, and the collection object.
Collection pages are where customers browse and discover products. Understanding how collection templates work in Online Store 2.0 helps you build flexible, merchant-customizable shopping experiences.
The Collection Object
When a customer visits a collection URL, Shopify provides the collection object:
{{ collection.title }} {# "Summer Collection" #}{{ collection.description }} {# Collection description HTML #}{{ collection.handle }} {# "summer-collection" #}{{ collection.url }} {# "/collections/summer-collection" #}{{ collection.image }} {# Collection image object #}{{ collection.products }} {# Paginated array of products #}{{ collection.products_count }} {# Total number of products #}{{ collection.all_products_count }} {# Count before filters #}JSON Template Structure
Collection templates in Online Store 2.0 use JSON to define sections:
{# templates/collection.json #}{ "sections": { "banner": { "type": "collection-banner", "settings": { "show_collection_description": true, "show_collection_image": true } }, "product-grid": { "type": "collection-product-grid", "settings": { "products_per_page": 24, "columns_desktop": 4, "enable_filtering": true, "enable_sorting": true } } }, "order": ["banner", "product-grid"]}Template File Organization
A typical collection template setup:
templates/├── collection.json # Default collection template├── collection.sale.json # Alternate: Sale collections└── collection.featured.json # Alternate: Featured collections
sections/├── collection-banner.liquid├── collection-product-grid.liquid├── collection-filters.liquid└── collection-empty.liquid
snippets/├── product-card.liquid├── product-card-badges.liquid├── pagination.liquid└── filter-checkbox.liquidMain Template Sections
A collection page typically has these sections:
1. Collection Banner
Shows collection title, description, and optional image:
{# sections/collection-banner.liquid #}<div class="collection-banner"> {%- if collection.image and section.settings.show_image -%} <div class="collection-banner__image"> <img src="{{ collection.image | image_url: width: 1920 }}" alt="{{ collection.image.alt | default: collection.title }}" > </div> {%- endif -%}
<div class="collection-banner__content"> <h1 class="collection-banner__title">{{ collection.title }}</h1>
{%- if collection.description != blank and section.settings.show_description -%} <div class="collection-banner__description"> {{ collection.description }} </div> {%- endif -%}
<p class="collection-banner__count"> {{ collection.products_count }} {{ collection.products_count | pluralize: 'product', 'products' }} </p> </div></div>2. Product Grid
Displays the products with sorting, filtering, and pagination:
{# sections/collection-product-grid.liquid #}<div class="collection-grid"> {# Toolbar: Sorting, Filtering, View options #} <div class="collection-grid__toolbar"> {%- if section.settings.enable_sorting -%} {% render 'collection-sorting' %} {%- endif -%}
{%- if section.settings.enable_filtering -%} {% render 'collection-filters' %} {%- endif -%} </div>
{# Product grid #} {%- paginate collection.products by section.settings.products_per_page -%} {%- if collection.products.size > 0 -%} <ul class="product-grid" style="--columns: {{ section.settings.columns }};"> {%- for product in collection.products -%} <li class="product-grid__item"> {% render 'product-card', product: product %} </li> {%- endfor -%} </ul>
{%- if paginate.pages > 1 -%} {% render 'pagination', paginate: paginate %} {%- endif -%} {%- else -%} {% render 'collection-empty' %} {%- endif -%} {%- endpaginate -%}</div>The Paginate Tag
Collection products are paginated. Wrap your product loop with paginate:
{%- paginate collection.products by 24 -%} {# collection.products now contains only current page products #} {# paginate object provides pagination info #}
Total products: {{ paginate.items }} Current page: {{ paginate.current_page }} Total pages: {{ paginate.pages }} Products on this page: {{ collection.products.size }}
{%- for product in collection.products -%} {{ product.title }} {%- endfor -%}{%- endpaginate -%}Accessing Products
Current Page Products
{%- paginate collection.products by 24 -%} {%- for product in collection.products -%} {{ product.title }} {%- endfor -%}{%- endpaginate -%}All Products (Not Recommended)
{# This loads ALL products - avoid for large collections #}{%- for product in collection.all_products -%} {{ product.title }}{%- endfor -%}Section Schema
A comprehensive collection grid schema:
{% schema %}{ "name": "Collection Product Grid", "settings": [ { "type": "header", "content": "Layout" }, { "type": "range", "id": "products_per_page", "label": "Products per page", "min": 8, "max": 48, "step": 4, "default": 24 }, { "type": "range", "id": "columns_desktop", "label": "Desktop columns", "min": 2, "max": 5, "step": 1, "default": 4 }, { "type": "range", "id": "columns_mobile", "label": "Mobile columns", "min": 1, "max": 2, "step": 1, "default": 2 }, { "type": "header", "content": "Features" }, { "type": "checkbox", "id": "enable_sorting", "label": "Enable sorting", "default": true }, { "type": "checkbox", "id": "enable_filtering", "label": "Enable filtering", "default": true }, { "type": "select", "id": "filter_type", "label": "Filter style", "options": [ { "value": "horizontal", "label": "Horizontal" }, { "value": "sidebar", "label": "Sidebar" }, { "value": "drawer", "label": "Drawer" } ], "default": "horizontal" }, { "type": "header", "content": "Product cards" }, { "type": "checkbox", "id": "show_vendor", "label": "Show vendor", "default": false }, { "type": "checkbox", "id": "show_rating", "label": "Show rating", "default": false }, { "type": "select", "id": "image_ratio", "label": "Image ratio", "options": [ { "value": "natural", "label": "Natural" }, { "value": "square", "label": "Square (1:1)" }, { "value": "portrait", "label": "Portrait (3:4)" }, { "value": "landscape", "label": "Landscape (4:3)" } ], "default": "portrait" } ]}{% endschema %}Alternate Collection Templates
Create specialized templates for different collection types:
Sale Template
{# templates/collection.sale.json #}{ "sections": { "banner": { "type": "collection-banner", "settings": { "background_color": "#dc2626", "text_color": "#ffffff" } }, "countdown": { "type": "sale-countdown", "settings": { "end_date": "2024-12-31" } }, "product-grid": { "type": "collection-product-grid", "settings": { "show_compare_price": true, "show_discount_badge": true } } }, "order": ["banner", "countdown", "product-grid"]}Featured Template
{# templates/collection.featured.json #}{ "sections": { "hero": { "type": "collection-hero", "settings": { "full_width": true, "height": "large" } }, "story": { "type": "rich-text", "settings": {} }, "product-grid": { "type": "collection-product-grid" }, "newsletter": { "type": "newsletter" } }, "order": ["hero", "story", "product-grid", "newsletter"]}Collection-Specific Data
Check collection properties for conditional logic:
{# Check if collection is empty #}{%- if collection.products.size == 0 -%} {% render 'collection-empty' %}{%- endif -%}
{# Check if it's the "all" collection #}{%- if collection.handle == 'all' -%} <p>Browsing all products</p>{%- endif -%}
{# Check for filtered state #}{%- if collection.filters.size > 0 -%} {%- assign active_filters = collection.filters | where: 'active_values' -%} {%- if active_filters.size > 0 -%} <p>Showing filtered results</p> {%- endif -%}{%- endif -%}
{# Check current sort order #}{%- if collection.sort_by != blank -%} <p>Sorted by: {{ collection.sort_by }}</p>{%- endif -%}Complete Template Example
{# templates/collection.json #}{ "sections": { "announcement": { "type": "announcement-bar", "disabled": true, "settings": {} }, "banner": { "type": "collection-banner", "settings": { "show_image": true, "show_description": true, "image_height": "medium" } }, "toolbar": { "type": "collection-toolbar", "settings": { "show_product_count": true, "show_sort": true, "show_filter_toggle": true } }, "main": { "type": "collection-product-grid", "settings": { "products_per_page": 24, "columns_desktop": 4, "columns_tablet": 3, "columns_mobile": 2, "enable_quick_add": true, "show_secondary_image": true } }, "recently-viewed": { "type": "recently-viewed", "disabled": true, "settings": {} } }, "order": [ "announcement", "banner", "toolbar", "main", "recently-viewed" ]}Practice Exercise
Create a collection template that:
- Has a banner with title and product count
- Shows a product grid with 24 products per page
- Supports 4 columns on desktop, 2 on mobile
- Includes a toolbar for sorting
- Has pagination at the bottom
Map out which sections you need and what settings each should have.
Key Takeaways
- Collection templates are JSON in Online Store 2.0
- Use
paginatetag to handle product pagination - The
collectionobject provides all collection data - Split functionality into sections: banner, grid, filters
- Create alternate templates for special collections
- Schema settings give merchants control
- Check collection state for empty, filtered, sorted states
What’s Next?
With the architecture understood, the next lesson covers Building a Collection Banner Section for displaying collection headers.
Finished this lesson?
Mark it complete to track your progress.
Discussion
Loading comments...