Templates, Layouts, and the Rendering Pipeline Intermediate 10 min read

Creating Custom Templates

Learn how to create alternate templates for products, collections, and pages to support different layouts and use cases in your Shopify theme.

Not every product page should look the same. Some products need video galleries, others need size guides, and some need completely different layouts. Custom templates let you create variations that merchants can assign to specific products, collections, or pages.

What Are Custom Templates?

Custom templates (also called alternate templates) are variations of the default template for a resource type. They use a naming convention with a suffix:

templates/
├── product.json # Default product template
├── product.with-video.json # Alternate for products with video
├── product.simple.json # Minimal product layout
├── product.preorder.json # Pre-order products
└── product.bundle.json # Product bundles

The suffix after the dot becomes the template name that merchants see in the Shopify admin.

Creating Your First Custom Template

Let’s create a product template for items that have video content.

Step 1: Create the Template File

Create templates/product.with-video.json:

{
"sections": {
"main": {
"type": "main-product-video",
"settings": {
"enable_video_autoplay": false,
"video_position": "left"
},
"blocks": {
"title": { "type": "title" },
"price": { "type": "price" },
"variant_picker": { "type": "variant_picker" },
"buy_buttons": { "type": "buy_buttons" },
"description": { "type": "description" }
},
"block_order": ["title", "price", "variant_picker", "buy_buttons", "description"]
},
"video_gallery": {
"type": "product-video-gallery",
"settings": {
"heading": "See it in action"
}
},
"recommendations": {
"type": "product-recommendations",
"settings": {
"heading": "You may also like"
}
}
},
"order": ["main", "video_gallery", "recommendations"]
}

Step 2: Create Supporting Sections

The template references sections that may need to be created:

{# sections/main-product-video.liquid #}
<section class="product-video-layout">
<div class="product-video-layout__media">
{%- if product.featured_media.media_type == 'video' -%}
{{ product.featured_media | video_tag: autoplay: section.settings.enable_video_autoplay, loop: true, muted: true }}
{%- else -%}
{{ product.featured_image | image_url: width: 800 | image_tag }}
{%- endif -%}
</div>
<div class="product-video-layout__info">
{%- for block in section.blocks -%}
{%- case block.type -%}
{%- when 'title' -%}
<h1 {{ block.shopify_attributes }}>{{ product.title }}</h1>
{%- when 'price' -%}
{% render 'price', product: product %}
{%- when 'variant_picker' -%}
{% render 'variant-picker', product: product %}
{%- when 'buy_buttons' -%}
{% render 'buy-buttons', product: product %}
{%- when 'description' -%}
<div {{ block.shopify_attributes }}>{{ product.description }}</div>
{%- endcase -%}
{%- endfor -%}
</div>
</section>
{% schema %}
{
"name": "Product (Video)",
"settings": [
{
"type": "checkbox",
"id": "enable_video_autoplay",
"label": "Autoplay video",
"default": false
},
{
"type": "select",
"id": "video_position",
"label": "Video position",
"options": [
{ "value": "left", "label": "Left" },
{ "value": "right", "label": "Right" }
],
"default": "left"
}
],
"blocks": [
{ "type": "title", "name": "Title" },
{ "type": "price", "name": "Price" },
{ "type": "variant_picker", "name": "Variant picker" },
{ "type": "buy_buttons", "name": "Buy buttons" },
{ "type": "description", "name": "Description" }
]
}
{% endschema %}

Step 3: Assign to Products

In the Shopify admin:

  1. Go to Products
  2. Select a product
  3. In the “Theme template” section, choose “product.with-video”
  4. Save

Common Custom Template Patterns

Collection Templates

templates/
├── collection.json # Default grid layout
├── collection.list.json # List view layout
├── collection.sidebar.json # With filter sidebar
└── collection.lookbook.json # Lookbook/gallery style

List View Template:

{
"sections": {
"banner": {
"type": "collection-banner"
},
"main": {
"type": "main-collection-list",
"settings": {
"products_per_page": 12,
"show_description": true,
"show_quick_add": true
}
}
},
"order": ["banner", "main"]
}

Page Templates

templates/
├── page.json # Default page
├── page.contact.json # Contact form
├── page.faq.json # FAQ accordion
├── page.about.json # About with team section
└── page.landing.json # Full-width landing page

Contact Page Template:

{
"sections": {
"main": {
"type": "main-page",
"settings": {
"padding_top": 60,
"padding_bottom": 20
}
},
"contact_form": {
"type": "contact-form",
"settings": {
"heading": "Get in touch",
"show_phone_field": true,
"show_subject_field": true
}
},
"map": {
"type": "map",
"settings": {
"heading": "Visit us"
}
}
},
"order": ["main", "contact_form", "map"]
}

FAQ Page Template:

{
"sections": {
"main": {
"type": "main-page",
"settings": {}
},
"faq": {
"type": "faq-accordion",
"blocks": {
"q1": {
"type": "question",
"settings": {
"question": "How do I track my order?",
"answer": "<p>You can track your order using the link in your shipping confirmation email.</p>"
}
},
"q2": {
"type": "question",
"settings": {
"question": "What is your return policy?",
"answer": "<p>We accept returns within 30 days of purchase.</p>"
}
}
},
"block_order": ["q1", "q2"]
}
},
"order": ["main", "faq"]
}

Choosing Templates vs Conditional Logic

Sometimes you can achieve the same result with conditional logic in a single template. How do you choose?

Use Custom Templates When:

  • The layout is significantly different
  • Different sections are needed entirely
  • Merchants need to customize each variant separately
  • The difference is visual/structural, not content-based

Use Conditional Logic When:

  • Small variations based on product tags or metafields
  • Showing/hiding one element
  • The core layout remains the same

Conditional Logic Example:

{# In a single product section #}
{% if product.tags contains 'preorder' %}
<span class="badge badge--preorder">Pre-Order</span>
<p class="preorder-notice">Expected to ship in 2-3 weeks</p>
{% endif %}
{% if product.metafields.custom.size_guide %}
{% render 'size-guide', guide: product.metafields.custom.size_guide %}
{% endif %}

This approach keeps one template but adapts based on product data.

Template Naming Best Practices

Use Descriptive Suffixes

✓ product.with-video.json # Clear purpose
✓ product.preorder.json # Obvious use case
✓ collection.sidebar.json # Describes layout
✗ product.v2.json # Vague
✗ product.new.json # Meaningless
✗ collection.test.json # Not for production

Use Consistent Patterns

If you use “with-” for additions, stick with it:

product.with-video.json
product.with-size-guide.json
product.with-360-view.json

Keep It Merchant-Friendly

The suffix appears in the admin. Choose names merchants will understand:

✓ "with-video" → Merchant sees: "product.with-video"
✓ "lookbook" → Merchant sees: "collection.lookbook"
✗ "v2-layout" → Confusing for merchants
✗ "custom-abc" → What does this do?

Organizing Multiple Templates

For themes with many templates, document them:

{# In your theme documentation or README #}
## Product Templates
| Template | Use For |
|----------|---------|
| product | Standard products |
| product.with-video | Products with video content |
| product.preorder | Pre-order items |
| product.bundle | Product bundles |
## Collection Templates
| Template | Use For |
|----------|---------|
| collection | Standard grid layout |
| collection.list | List view with descriptions |
| collection.lookbook | Fashion lookbook style |

Testing Custom Templates

1. Create Test Resources

Create test products/collections/pages specifically for template testing:

  • “Test Product - Video Template”
  • “Test Collection - Sidebar Template”
  • “Test Page - Contact Template”

2. Test in Theme Editor

  1. Open the theme editor
  2. Navigate to the page using the template
  3. Verify all sections appear correctly
  4. Test customization options
  5. Check responsive behavior

3. Test Template Assignment

  1. Assign the template to a resource
  2. View the live page
  3. Switch templates and verify the change
  4. Test reverting to default

Practice Exercise

Create a page.landing.json template for marketing landing pages with:

  1. A full-width hero section
  2. A features grid section
  3. A testimonials section
  4. A newsletter signup section
{
"sections": {
"hero": {
"type": "hero-banner",
"settings": {
"full_width": true,
"height": "large",
"text_alignment": "center"
}
},
"features": {
"type": "features-grid",
"settings": {
"heading": "Why Choose Us",
"columns": 3
},
"blocks": {
"feature1": {
"type": "feature",
"settings": {
"icon": "truck",
"heading": "Free Shipping",
"text": "On orders over $50"
}
},
"feature2": {
"type": "feature",
"settings": {
"icon": "shield",
"heading": "Secure Checkout",
"text": "100% protected payments"
}
},
"feature3": {
"type": "feature",
"settings": {
"icon": "refresh",
"heading": "Easy Returns",
"text": "30-day return policy"
}
}
},
"block_order": ["feature1", "feature2", "feature3"]
},
"testimonials": {
"type": "testimonials",
"settings": {
"heading": "What Our Customers Say"
}
},
"newsletter": {
"type": "newsletter",
"settings": {
"heading": "Stay Updated",
"subheading": "Subscribe for exclusive offers and updates"
}
}
},
"order": ["hero", "features", "testimonials", "newsletter"]
}

Key Takeaways

  1. Custom templates use naming suffixes like product.with-video.json
  2. The suffix becomes the template name merchants see in admin
  3. Choose templates over conditionals for significantly different layouts
  4. Choose conditionals over templates for small, data-driven variations
  5. Use descriptive names that merchants will understand
  6. Document your templates so merchants know when to use each one
  7. Test thoroughly including template assignment and customization

What’s Next?

Now that you can create custom templates, the next lesson covers Template-Specific vs Global Sections and how to control where sections can appear in your theme.

Finished this lesson?

Mark it complete to track your progress.

Discussion

Loading comments...