How to Create New Templates in Shopify Theme Editor (Step-by-Step Guide 2026)
What Are Templates in Shopify?
A template is a blueprint composed of sections, which are themselves composed of blocks. You can add, remove, and rearrange sections and blocks within a template using the theme editor. Changes you make to a template apply to all pages that use it. For example, adding a signup form to a collection template will add it to all collection pages using that template. By creating alternate templates, you can have unique layouts for different products or collections. For instance, one product template could have a gift message field, while another might not.
In this article, you will learn how to create new templates in Shopify Theme Editor.
Why Create New Templates?
There are several benefits of creating new templates, such as:
- They make it easier for people with limited design or technical skills to create professional-looking content.
- Templates provide a starting point, allowing you to focus on the content itself rather than its presentation.
- Instead of designing a new document, website page, or presentation from scratch each time, a template provides a pre-formatted structure that saves time and effort.
If you are migrating from another platform to Shopify and need templates set up correctly from day one, our Shopify Migration Experts ensure your store structure, templates, and content are transferred without issues.
Types of Templates You Can Create
There are several kinds of templates available that you can create. Some of these are listed below.
- Product template (product.json)
- Collection template (collection.json)
- Page template (page.json)
- Blog template (blog.json)
- Article template (article.json)
- Cart template (cart.json)
- Search template (search.json) and more.
Methods for Creating Templates in Shopify
There are several ways to create a template in Shopify. Some of these are given below.
- Create a Template Using the Shopify Theme Editor
- Create a Template using the Custom Coding
If you're not confident editing theme code yourself, our Shopify Custom Theme Development Services can handle template creation and customization professionally for your store.
Method 1: Create a Template Using the Shopify Theme Editor
To create a new template in the Shopify theme editor, go to Online Store > Themes > Customize. Use a dropdown menu at the top to select a template type, such as Product or Page. Click Create Template. Please give it a unique name. Choose a base template to build from, and then click Create template again. After creation, you can customize the new template by adding or rearranging sections and blocks. Follow these steps to create a new template using the Shopify Theme Editor.
Step 1: Navigate to Online Store > Themes > Customize.

Step 2: Select the template from the dropdown that you want to create, such as the Product template.

Step 3: Click the Create template button.

Step 4: Add the unique name, select the base template, and click the Create template button.

Step 5: After creating the template, navigate to the newly created template and customize the layout by adding or rearranging new sections as needed.

Step 6: Navigate to Shopify Admin > Products.

Step 7: Select the product where you want to assign this new template.

Step 8: Scroll down to the Theme Template section and select the template from the dropdown that you have created.

Step 9: Save the changes.

Note: This process applies to all content types, including Collections, Pages, Blogs, Articles, etc. Add the relevant template and attach it to the appropriate element.
For developers looking to go beyond Shopify's built-in templating system, headless CMS development services offer greater flexibility in managing and delivering content across multiple frontends.
Method 2: Create a Template Using the Custom Coding
To create a new template in the Custom Coding, go to Online Store > Themes > Edit Code. Go to the templates folder and add a new template file for a product template, name it something like product.custom-product.json. Follow these steps to create a new template using the custom coding.
Step 1: Navigate to Online Store > Themes > Edit Code.

Step 2: Scroll down to the Templates Folder.

Step 3: Click the Add file button at the top of the panel.

- Products: product.custom-product.json
- Collection: collection.custom-collection.json
- Collection List: list-collections.custom-list-collections.json
- Blog: blog.custom-blog.json
- Article: article.custom-article.json
- Page: page.custom-page.json
Step 5: If you are using a Vintage Theme, then you can use the following naming conventions.
- Products: product.custom-product.liquid
- Collection: collection.custom-collection.liquid
- Collection List: list-collections.custom-list-collections.liquid
- Blog: blog.custom-blog.liquid
- Article: article.custom-article.liquid
- Page: page.custom-page.liquid
Step 6: Name it something like product.custom-product.json.

Step 7: Add the following JSON data to your file.
{
"sections": {
"main": {
"type": "main-product",
"blocks": {
"title": {
"type": "title",
"settings": {}
},
"vendor": {
"type": "text",
"settings": {
"text": "{{ product.vendor }}",
"text_style": "body"
}
},
"variant_picker": {
"type": "variant_picker",
"settings": {
"picker_type": "button"
}
},
"quantity_selector": {
"type": "quantity_selector",
"settings": {}
},
"price": {
"type": "price",
"settings": {}
},
"buy_buttons": {
"type": "buy_buttons",
"settings": {
"show_dynamic_checkout": true,
"show_gift_card_recipient": false
}
},
"description": {
"type": "description",
"settings": {}
},
"share": {
"type": "share",
"disabled": true,
"settings": {
"share_label": "Share"
}
}
},
"block_order": [
"title",
"vendor",
"variant_picker",
"quantity_selector",
"price",
"buy_buttons",
"description",
"share"
],
"settings": {
"enable_sticky_info": true,
"media_size": "medium",
"constrain_to_viewport": false,
"media_fit": "cover",
"gallery_layout": "stacked",
"media_position": "left",
"image_zoom": "none",
"mobile_thumbnails": "hide",
"hide_variants": true,
"enable_video_looping": false,
"padding_top": 64,
"padding_bottom": 0
}
},
"17563055301de075e3": {
"type": "apps",
"blocks": {
"kiwi_size_chart_recommender_kiwi_sizing_xAhML7": {
"type": "shopify://apps/kiwi-size-chart-recommender/blocks/kiwiSizing/b7369922-bf15-44ce-a121-a22a8fcbc4b0",
"settings": {
"product": "{{product}}",
"waitForElementSelector": "",
"waitForElementDelay": 5
}
}
},
"block_order": [
"kiwi_size_chart_recommender_kiwi_sizing_xAhML7"
],
"disabled": true,
"settings": {
"include_margins": true
}
},
"related-products": {
"type": "related-products",
"disabled": true,
"settings": {
"heading": "Related products",
"heading_size": "h2",
"products_to_show": 4,
"columns_desktop": 4,
"color_scheme": "background-1",
"image_ratio": "portrait",
"show_secondary_image": true,
"show_vendor": false,
"show_rating": false,
"columns_mobile": "2",
"padding_top": 48,
"padding_bottom": 28
}
},
"1753871364c560f160": {
"type": "apps",
"blocks": {
"judge_me_reviews_review_widget_9hgxkm": {
"type": "shopify://apps/judge-me-reviews/blocks/review_widget/61ccd3b1-a9f2-4160-9fe9-4fec8413e5d8",
"settings": {
"review_data": "sample_data",
"show_shop_reviews": false,
"empty_state": "empty_widget",
"max_width": 1200
}
}
},
"block_order": [
"judge_me_reviews_review_widget_9hgxkm"
],
"disabled": true,
"settings": {
"include_margins": true
}
}
},
"order": [
"main",
"17563055301de075e3",
"related-products",
"1753871364c560f160"
]
}
>
Step 8: For a Vintage theme, add code like this.
<div class="product-grid grid grid-cols-1 md:grid-cols-2 gap-8">
<section class="product-gallery" aria-label="Product images">
<div class="main-image mb-4">
{% assign featured = product.featured_image | default: product.images.first %}
{% if featured %}
<img id="ProductImage" src="{{ featured.src | img_url: '1024x1024' }}" alt="{{ featured.alt | escape }}" loading="lazy" class="w-full rounded-lg shadow-md">
{% endif %}
</div>
{% if product.images.size > 1 %}
<div class="thumbs flex gap-3 overflow-x-auto" role="list">
{% for img in product.images %}
<button class="thumb" type="button" aria-label="View image {{ forloop.index }}" data-image-src="{{ img.src | img_url: '1024x1024' }}">
<img src="{{ img.src | img_url: '200x200' }}" alt="{{ img.alt | escape }}" class="w-20 h-20 object-cover rounded">
</button>
{% endfor %}
</div>
{% endif %}
</section>
<section class="product-meta">
<h1 class="product-title text-2xl font-serif mb-2">{{ product.title }}</h1>
{% if product.compare_at_price > product.price %}
<div class="price flex items-baseline gap-2 mb-3">
<span class="price--sale text-xl font-bold">{{ product.price | money }}</span>
<span class="price--compare line-through text-sm">{{ product.compare_at_price | money }}</span>
</div>
{% else %}
<div class="price mb-3"><span class="text-xl font-bold">{{ product.price | money }}</span></div>
{% endif %}
<div class="short-description mb-4 text-gray-700">{{ product.description | strip_html | truncate: 200 }}</div>
{% if product.metafields.custom and product.metafields.custom.options != blank %}
<div class="product-options-metafield mb-4">
<h3 class="text-sm font-semibold">Additional options</h3>
<p class="text-sm">{{ product.metafields.custom.options }}</p>
</div>
{% endif %}
<form id="AddToCartForm" method="post" action="/cart/add" class="space-y-4" novalidate>
<input type="hidden" name="id" value="{{ product.selected_or_first_available_variant.id }}" id="ProductVariantInput">
{% if product.options.size > 1 or product.options.first != 'Default Title' %}
<div class="variant-selectors space-y-2">
{% for option in product.options_with_values %}
<label class="block text-sm font-medium">{{ option.name }}</label>
<div class="options flex gap-2" role="radiogroup" aria-label="{{ option.name }}">
{% for value in option.values %}
{% assign variant_id = product.variants | where: option.position, value | map: 'id' | first %}
<button type="button" class="variant-btn px-3 py-1 border rounded" data-option-index="{{ forloop.index0 }}" data-option-value="{{ value }}">{{ value }}</button>
{% endfor %}
</div>
{% endfor %}
</div>
{% endif %}
<label for="quantity" class="sr-only">Quantity</label>
<div class="quantity flex items-center gap-2">
<button type="button" class="qty-decrease px-3 py-1 border rounded" aria-label="Decrease quantity">-</button>
<input id="quantity" name="quantity" type="number" min="1" value="1" class="w-16 text-center border rounded" aria-label="Quantity">
<button type="button" class="qty-increase px-3 py-1 border rounded" aria-label="Increase quantity">+</button>
</div>
<div>
{% if product.available %}
<button type="submit" id="AddToCartButton" class="add-to-cart-btn bg-amber-700 hover:bg-amber-800 text-white px-6 py-3 rounded mt-3">Add to cart</button>
{% else %}
<button type="button" class="sold-out-btn bg-gray-400 text-white px-6 py-3 rounded mt-3" disabled>Sold out</button>
{% endif %}
</div>
<div id="variant-availability" class="sr-only" aria-live="polite"></div>
</form>
<div class="product-actions mt-4 flex gap-3">
<a href="mailto:?subject={{ product.title | url_encode }}&body={{ shop.url }}{{ product.url }}" class="underline text-sm">Share by email</a>
<a href="https://www.pinterest.com/pin/create/button/?url={{ shop.url }}{{ product.url }}&media={{ featured.src | img_url: '1024x1024' }}&description={{ product.title | url_encode }}" target="_blank" rel="noopener" class="underline text-sm">Pin</a>
</div>
</section>
</div>
<div class="product-tabs mt-8">
<div class="tabs-nav flex gap-4 mb-4">
<button class="tab-btn active" data-tab="description">Description</button>
<button class="tab-btn" data-tab="reviews">Reviews</button>
</div>
<div class="tab-panels">
<div id="description" class="tab-panel">
{{ product.description }}
</div>
<div id="reviews" class="tab-panel hidden">
{% if shop.metafields.reviews and shop.metafields.reviews[product.handle] %}
{{ shop.metafields.reviews[product.handle] }}
{% else %}
<p class="text-sm">Reviews are not enabled on this demo. Integrate a review app or use Shopify Product Reviews.</p>
{% endif %}
</div>
</div>
</div>
<section class="related-products mt-12">
<h3 class="text-xl font-semibold mb-4">You may also like</h3>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
{% for related in collections.all.products | where: 'id', '!=', product.id | limit:4 %}
<article class="related-card border rounded p-3 text-center">
<a href="{{ related.url }}">
{% if related.featured_image %}
<img src="{{ related.featured_image | img_url: '300x300' }}" alt="{{ related.title }}" class="mx-auto mb-2">
{% endif %}
<h4 class="text-sm">{{ related.title }}</h4>
<div class="text-sm">{{ related.price | money }}</div>
</a>
</article>
{% endfor %}
</div>
</section>
<style>
.product-grid {
display: grid;
grid-template-columns: 1fr;
gap: 2rem;
}
@media (min-width: 768px) {
.product-grid {
grid-template-columns: 1fr 1fr;
}
}
.product-gallery .main-image img {
width: 100%;
border-radius: 12px;
box-shadow: 0 4px 18px rgba(0,0,0,0.15);
}
.thumbs {
display: flex;
gap: 12px;
padding-top: 4px;
}
.thumbs .thumb img {
width: 80px;
height: 80px;
border-radius: 8px;
object-fit: cover;
transition: outline 0.2s ease, transform 0.2s ease;
}
.thumbs .thumb:hover img,
.thumbs .thumb:focus img {
outline: 2px solid #b08968;
transform: scale(1.05);
}
.product-title {
font-size: 1.8rem;
font-weight: 600;
font-family: Georgia, "Times New Roman", serif;
color: #3b302a;
}
.price--sale {
color: #8b4513;
}
.price--compare {
color: #9c8f85;
}
.short-description {
color: #4b4b4b;
line-height: 1.55;
}
.variant-btn {
border: 1px solid #cfc6bf;
padding: 6px 12px;
background: #fff;
border-radius: 6px;
cursor: pointer;
transition: all 0.2s ease;
font-size: 14px;
}
.variant-btn:hover,
.variant-btn.selected {
background: #f3e9dc;
border-color: #a68a74;
color: #3b302a;
font-weight: 600;
}
.quantity button {
border: 1px solid #cfc6bf;
border-radius: 6px;
background: #faf6f2;
cursor: pointer;
transition: background 0.2s;
}
.quantity button:hover {
background: #efe6dd;
}
#quantity {
border-radius: 6px;
padding: 4px;
border: 1px solid #d7cfc7;
}
.add-to-cart-btn {
width: 100%;
padding: 14px;
font-size: 16px;
font-weight: 600;
border-radius: 8px;
background: #7d4f2f;
color: #fff;
transition: background 0.2s ease;
}
.add-to-cart-btn:hover {
background: #6c4429;
}
.sold-out-btn {
width: 100%;
padding: 14px;
border-radius: 8px;
}
.tabs-nav .tab-btn {
padding: 8px 14px;
border-bottom: 2px solid transparent;
font-weight: 600;
cursor: pointer;
transition: border-color 0.2s ease, color 0.2s;
background: none;
}
.tabs-nav .tab-btn.active {
border-color: #7d4f2f;
color: #7d4f2f;
}
.tab-panel {
padding-top: 10px;
font-size: 15px;
color: #473f38;
line-height: 1.65;
}
.hidden {
display: none;
}
.related-products h3 {
font-family: Georgia, serif;
color: #3b302a;
}
.related-card {
border: 1px solid #e5ddd5;
border-radius: 10px;
background: #fff;
transition: box-shadow 0.2s ease, transform 0.2s;
}
.related-card:hover {
transform: translateY(-4px);
box-shadow: 0 6px 16px rgba(0,0,0,0.12);
}
.related-card img {
border-radius: 8px;
width: 100%;
}
.related-card h4 {
margin-top: 6px;
font-weight: 600;
font-size: 14px;
color: #3b302a;
}
.related-card div {
color: #6b5d55;
font-size: 14px;
margin-top: 4px;
}
</style>
<script>
(function(){
document.querySelectorAll('.thumb').forEach(function(btn){
btn.addEventListener('click', function(){
var src = this.getAttribute('data-image-src');
var main = document.getElementById('ProductImage');
if(main && src){ main.src = src; }
});
});
document.querySelectorAll('.tab-btn').forEach(function(tabBtn){
tabBtn.addEventListener('click', function(){
document.querySelectorAll('.tab-btn').forEach(b=>b.classList.remove('active'));
this.classList.add('active');
var target = this.getAttribute('data-tab');
document.querySelectorAll('.tab-panel').forEach(function(panel){
panel.classList.toggle('hidden', panel.id !== target);
});
});
});
var qtyInput = document.getElementById('quantity');
document.querySelector('.qty-increase').addEventListener('click', function(){ qtyInput.value = parseInt(qtyInput.value || 1) + 1; });
document.querySelector('.qty-decrease').addEventListener('click', function(){ qtyInput.value = Math.max(1, parseInt(qtyInput.value || 1) - 1); });
var variantInput = document.getElementById('ProductVariantInput');
var variantBtnList = Array.from(document.querySelectorAll('.variant-btn'));
if(variantBtnList.length){
variantBtnList.forEach(function(btn){
btn.addEventListener('click', function(){
var optionIndex = parseInt(this.getAttribute('data-option-index'));
var optionValue = this.getAttribute('data-option-value');
variantBtnList.filter(b => b.getAttribute('data-option-index') == optionIndex).forEach(b => b.classList.remove('selected'));
this.classList.add('selected');
var selectedOptions = [];
var optionCount = {{ product.options.size }};
for(var i=0;i<optionCount;i++){
var sel = document.querySelector('.variant-btn[data-option-index="'+i+'"].selected');
selectedOptions[i] = sel ? sel.getAttribute('data-option-value') : null;
}
try{
var variants = {{ product.variants | json }};
var found = variants.find(function(v){
for(var i=0;i<optionCount;i++){
var optName = 'option' + (i+1);
if(selectedOptions[i] && v[optName] !== selectedOptions[i]) return false;
}
return true;
});
if(found){
variantInput.value = found.id;
document.getElementById('variant-availability').textContent = found.available ? 'In stock' : 'Out of stock';
}
} catch(e){ console.warn('Variant lookup failed', e); }
});
});
}
document.getElementById('AddToCartForm').addEventListener('submit', function(e){
});
})();
</script>
Step 9: Save the changes.
Conclusion
Creating templates in Shopify gives you full control over how different pages look and function across your store. Whether you use the Theme Editor for a no-code approach or dive into custom coding for more flexibility, both methods let you build unique layouts without affecting your other pages. Well-built templates improve the shopping experience and make it easier to manage your store as it grows. If you need help setting up custom templates the right way, our Shopify Custom Theme Development Services are built for exactly that. And if you want those pages to convert better, our Shopify CRO Services can help turn more visitors into buyers.