Templates, Layouts, and the Rendering Pipeline Beginner 12 min read

JSON Templates: Structure and Section Arrays

Learn how JSON templates work in Shopify Online Store 2.0, including their structure, section configuration, and how they enable flexible theme customization.

JSON templates are the foundation of Shopify’s Online Store 2.0 architecture. They define which sections appear on a page and in what order, while giving merchants the power to customize their store through the theme editor. Let’s explore how they work.

JSON vs Liquid Templates

Before Online Store 2.0, templates were .liquid files containing HTML and Liquid code:

{# Old approach: templates/product.liquid #}
<div class="product-page">
{% section 'product-main' %}
{% section 'product-recommendations' %}
</div>

The problem? Merchants couldn’t add, remove, or reorder sections. The template was locked to whatever sections the developer included.

JSON templates solve this by separating structure from content:

templates/product.json
{
"sections": {
"main": {
"type": "main-product"
},
"recommendations": {
"type": "product-recommendations"
}
},
"order": ["main", "recommendations"]
}

Now merchants can:

  • Add new sections between existing ones
  • Remove sections they don’t want
  • Reorder sections freely
  • Customize each section’s settings

JSON Template Structure

Every JSON template has the same basic structure:

{
"sections": {
"unique-key": {
"type": "section-file-name",
"settings": {}
}
},
"order": ["unique-key"]
}

The sections Object

Contains all sections that can appear in this template. Each section has:

  • A unique key: An identifier you create (e.g., “main”, “hero”, “featured-products”)
  • type: The filename of the section (without .liquid)
  • settings: Default values for section settings (optional)
  • blocks: Pre-configured blocks (optional)
{
"sections": {
"hero": {
"type": "image-banner",
"settings": {
"image": "shopify://shop_images/hero.jpg",
"heading": "Welcome to our store",
"button_label": "Shop Now",
"button_link": "/collections/all"
}
},
"featured": {
"type": "featured-collection",
"settings": {
"collection": "best-sellers",
"products_to_show": 8
}
}
},
"order": ["hero", "featured"]
}

The order Array

Defines the display order of sections. Only sections listed here will render:

{
"sections": {
"a": { "type": "section-a" },
"b": { "type": "section-b" },
"c": { "type": "section-c" }
},
"order": ["b", "a"]
}

In this example, section “c” won’t render because it’s not in the order array. Sections “b” and “a” render in that order.

Template Files by Page Type

Each page type has its own template file:

templates/
├── index.json # Homepage
├── product.json # Product pages
├── collection.json # Collection pages
├── page.json # Static pages
├── blog.json # Blog listing
├── article.json # Individual blog posts
├── cart.json # Cart page
├── search.json # Search results
├── customers/
│ ├── account.json # Customer account
│ ├── login.json # Login page
│ ├── register.json # Registration
│ ├── order.json # Order details
│ └── addresses.json # Address management
├── 404.json # Not found page
├── password.json # Password page
└── gift_card.liquid # Gift card (still uses .liquid)

A Complete Template Example

Here’s a real-world product.json:

{
"sections": {
"main": {
"type": "main-product",
"settings": {
"show_vendor": true,
"show_sku": false,
"enable_sticky_info": true
},
"blocks": {
"title": {
"type": "title"
},
"price": {
"type": "price"
},
"variant_picker": {
"type": "variant_picker",
"settings": {
"picker_type": "dropdown"
}
},
"quantity": {
"type": "quantity_selector"
},
"buy_buttons": {
"type": "buy_buttons",
"settings": {
"show_dynamic_checkout": true
}
},
"description": {
"type": "description"
}
},
"block_order": ["title", "price", "variant_picker", "quantity", "buy_buttons", "description"]
},
"recommendations": {
"type": "product-recommendations",
"settings": {
"heading": "You may also like",
"products_to_show": 4
}
}
},
"order": ["main", "recommendations"]
}

Blocks in Templates

Sections can have blocks, which are repeatable content units. The template can pre-configure them:

{
"sections": {
"main": {
"type": "main-product",
"blocks": {
"title": {
"type": "title"
},
"price": {
"type": "price"
}
},
"block_order": ["title", "price"]
}
},
"order": ["main"]
}

The block_order array determines the order blocks appear, similar to how order works for sections.

Homepage Template

The homepage (index.json) typically has multiple customizable sections:

{
"sections": {
"slideshow": {
"type": "slideshow",
"settings": {
"autoplay": true,
"autoplay_speed": 5
},
"blocks": {
"slide1": {
"type": "slide",
"settings": {
"heading": "New Arrivals",
"button_label": "Shop Now",
"button_link": "/collections/new"
}
},
"slide2": {
"type": "slide",
"settings": {
"heading": "Sale",
"button_label": "Save Big",
"button_link": "/collections/sale"
}
}
},
"block_order": ["slide1", "slide2"]
},
"featured_collection": {
"type": "featured-collection",
"settings": {
"heading": "Best Sellers",
"collection": "best-sellers"
}
},
"image_with_text": {
"type": "image-with-text",
"settings": {
"layout": "image_first"
}
},
"newsletter": {
"type": "newsletter",
"settings": {
"heading": "Subscribe to our newsletter"
}
}
},
"order": ["slideshow", "featured_collection", "image_with_text", "newsletter"]
}

Collection Template

Collection pages show products with filtering and sorting:

{
"sections": {
"banner": {
"type": "collection-banner",
"settings": {
"show_collection_image": true,
"show_collection_description": true
}
},
"main": {
"type": "main-collection",
"settings": {
"products_per_page": 24,
"columns_desktop": 4,
"enable_filtering": true,
"enable_sorting": true,
"filter_type": "vertical"
}
}
},
"order": ["banner", "main"]
}

How Merchants Customize Templates

When a merchant opens the theme editor:

  1. They select a page type (e.g., “Product pages”)
  2. They see all sections defined in that template
  3. They can:
    • Click any section to edit its settings
    • Drag sections to reorder them
    • Click “Add section” to insert new sections
    • Remove sections they don’t want

The theme editor saves these changes to config/settings_data.json, not the template file itself. This means:

  • Your template file is the default configuration
  • Merchant customizations are stored separately
  • Reverting to defaults restores your template’s settings

Template Naming Conventions

Standard Templates

Use the exact names Shopify expects:

TemplatePurpose
index.jsonHomepage
product.jsonDefault product page
collection.jsonDefault collection page
page.jsonDefault static page
blog.jsonBlog listing page
article.jsonIndividual article page
cart.jsonCart page
search.jsonSearch results
404.jsonPage not found

Alternate Templates

Create variations with a suffix:

TemplatePurpose
product.with-video.jsonProduct with video gallery
product.simple.jsonMinimal product layout
collection.sidebar.jsonCollection with sidebar
page.contact.jsonContact page layout
page.faq.jsonFAQ page layout

The part after the dot (e.g., “with-video”) becomes selectable in the Shopify admin.

Linking Section Files

Templates reference sections by their filename (minus .liquid):

{
"sections": {
"hero": {
"type": "hero-banner"
}
}
}

This looks for sections/hero-banner.liquid. The section file must:

  1. Exist in the sections/ directory
  2. Have a valid schema with at least a name
  3. Be compatible with the template type (if using enabled_on/disabled_on)

Default Settings

Template settings are defaults. If you specify:

{
"sections": {
"main": {
"type": "featured-collection",
"settings": {
"products_to_show": 8
}
}
}
}

New installations of your theme start with 8 products. Merchants can change this, and their changes persist. The template default only applies to:

  • Fresh theme installations
  • When a merchant clicks “Reset to defaults”

Practice Exercise

Create a collection.json template with:

  1. A collection banner section
  2. A main product grid section with filtering enabled
  3. A “Recently Viewed” section at the bottom
{
"sections": {
"banner": {
"type": "collection-banner",
"settings": {
"show_collection_image": true,
"show_collection_description": true
}
},
"product_grid": {
"type": "main-collection-product-grid",
"settings": {
"products_per_page": 16,
"columns_desktop": 4,
"columns_mobile": 2,
"enable_filtering": true,
"filter_type": "drawer",
"enable_sorting": true
}
},
"recently_viewed": {
"type": "recently-viewed",
"settings": {
"heading": "Recently Viewed",
"products_to_show": 4
}
}
},
"order": ["banner", "product_grid", "recently_viewed"]
}

Key Takeaways

  1. JSON templates define which sections appear on a page
  2. sections object contains all available sections with their settings
  3. order array determines the display sequence
  4. Blocks can be pre-configured within sections
  5. Merchants customize through the theme editor, stored in settings_data.json
  6. Alternate templates use suffixes like product.with-video.json
  7. Template files are defaults that apply to fresh installations

What’s Next?

Now that you understand JSON templates, the next lesson covers Creating Custom Templates for specific use cases like products with video or collections with different layouts.

Finished this lesson?

Mark it complete to track your progress.

Discussion

Loading comments...