This tutorial will walk you through creating your first custom theme template. You’ll learn the core concepts by building a simple product page layout with dynamic content.

Prerequisites: Basic knowledge of HTML and CSS. Access to your Quickbutik Control Panel.

What we’ll build

By the end of this tutorial, you’ll have created a custom product page that:

  • ✅ Displays product information dynamically
  • ✅ Shows product images in a gallery
  • ✅ Handles product variants and stock status
  • ✅ Includes an add-to-cart button

Step 1: Access the Theme Editor

First, let’s access your theme files:

1

Open Control Panel

Log into your Quickbutik store and navigate to Appearance → Theme

2

Access Code Editor

Click “Under the hood” to open the theme code editor

3

Find Product Template

Look for the product.html file in the file list - this controls how individual product pages are displayed

Step 2: Understanding the Basic Structure

Let’s start with a simple product page template:

product.html
<!DOCTYPE html>
<html>
<head>
    <title>{{product.title}} - {{shop.name}}</title>
    <meta name="description" content="{{seo.description}}">
</head>
<body>
    <div class="product-page">
        <!-- We'll build our product content here -->
    </div>
</body>
</html>

Step 3: Add Product Information

Now let’s add the core product information:

<div class="product-info">
    <h1 class="product-title">{{product.title}}</h1>
    
    <div class="product-price">
        {{#product.has_before_price}}
            <span class="before-price">{{product.before_price}}</span>
        {{/product.has_before_price}}
        <span class="current-price">{{product.price}}</span>
        <span class="currency">{{product.currency}}</span>
    </div>
    
    <div class="product-description">
        {{&product.description}}
    </div>
</div>

What’s happening here?

Price Display

We show both regular and sale prices, with the has_before_price conditional showing sale pricing only when relevant.

Stock Status

Using # and ^ operators to show different content based on whether the product is sold out.

Localization

The {{#lang}} wrapper automatically translates text based on your store’s language settings.

HTML Content

The & symbol in {{&product.description}} renders HTML content without escaping it.

Let’s create a dynamic image gallery:

Image Gallery
<div class="product-gallery">
    {{#product.images}}
        <div class="gallery-item">
            <img src="{{#img}}{{image}}_800x600{{/img}}" 
                 alt="{{alttext}}" 
                 data-id="{{image_id}}">
        </div>
    {{/product.images}}
    
    {{^product.images}}
        <!-- Fallback for products without images -->
        <div class="no-image">
            <span>{{#lang}}No image available{{/lang}}</span>
        </div>
    {{/product.images}}
</div>

The {{#img}} wrapper automatically optimizes images. The _800x600 suffix resizes the image to 800x600 pixels.

Step 5: Product Variants

If your product has variants (like size or color), let’s display them:

Product Variants
{{#product.hasOptions}}
<div class="product-options">
    <h3>{{#lang}}Options{{/lang}}</h3>
    
    {{#product.options}}
    <div class="option-group">
        <label>{{option_title}}</label>
        <select name="variant_{{option_title}}">
            {{#option_values}}
            <option value="{{id}}">{{name}}</option>
            {{/option_values}}
        </select>
    </div>
    {{/product.options}}
</div>
{{/product.hasOptions}}

Step 6: Add to Cart Button

Finally, let’s add a functional add-to-cart button:

Add to Cart
<div class="add-to-cart-section">
    {{^product.soldOut}}
        <form action="/cart/add" method="post">
            <input type="hidden" name="product_id" value="{{product.id}}">
            
            {{#product.hasOptions}}
                <!-- Include variant selection -->
                <div class="variant-selection">
                    <!-- Variant dropdowns will go here -->
                </div>
            {{/product.hasOptions}}
            
            <div class="quantity-selector">
                <label for="quantity">{{#lang}}Quantity{{/lang}}</label>
                <input type="number" name="quantity" value="1" min="1" id="quantity">
            </div>
            
            <button type="submit" class="btn-add-to-cart">
                {{#lang}}Add to Cart{{/lang}}
            </button>
        </form>
    {{/product.soldOut}}
    
    {{#product.soldOut}}
        <button class="btn-sold-out" disabled>
            {{#lang}}Out of Stock{{/lang}}
        </button>
    {{/product.soldOut}}
</div>

Step 7: Complete Example

Here’s your complete product page template:

<!DOCTYPE html>
<html>
<head>
    <title>{{product.title}} - {{shop.name}}</title>
    <meta name="description" content="{{seo.description}}">
    <style>
        /* Basic styling */
        .product-page { max-width: 1200px; margin: 0 auto; padding: 20px; }
        .product-gallery img { max-width: 100%; height: auto; }
        .before-price { text-decoration: line-through; color: #888; }
        .current-price { font-weight: bold; font-size: 1.2em; }
        .out-of-stock { color: #e74c3c; }
        .in-stock { color: #27ae60; }
        .btn-add-to-cart { background: #3498db; color: white; padding: 12px 24px; border: none; cursor: pointer; }
        .btn-sold-out { background: #95a5a6; color: white; padding: 12px 24px; border: none; }
    </style>
</head>
<body>
    <div class="product-page">
        <!-- Product Gallery -->
        <div class="product-gallery">
            {{#product.images}}
                <img src="{{#img}}{{image}}_800x600{{/img}}" alt="{{alttext}}">
            {{/product.images}}
        </div>
        
        <!-- Product Information -->
        <div class="product-info">
            <h1 class="product-title">{{product.title}}</h1>
            
            <div class="product-price">
                {{#product.has_before_price}}
                    <span class="before-price">{{product.before_price}}</span>
                {{/product.has_before_price}}
                <span class="current-price">{{product.price}}</span>
                <span class="currency">{{product.currency}}</span>
            </div>
            
            <div class="stock-status">
                {{#product.soldOut}}
                    <span class="out-of-stock">{{#lang}}Out of stock{{/lang}}</span>
                {{/product.soldOut}}
                {{^product.soldOut}}
                    <span class="in-stock">{{#lang}}In stock{{/lang}}</span>
                {{/product.soldOut}}
            </div>
            
            <div class="product-description">
                {{&product.description}}
            </div>
            
            <!-- Product Options -->
            {{#product.hasOptions}}
            <div class="product-options">
                {{#product.options}}
                <div class="option-group">
                    <label>{{option_title}}</label>
                    <select name="variant_{{option_title}}">
                        {{#option_values}}
                        <option value="{{id}}">{{name}}</option>
                        {{/option_values}}
                    </select>
                </div>
                {{/product.options}}
            </div>
            {{/product.hasOptions}}
            
            <!-- Add to Cart -->
            <div class="add-to-cart-section">
                {{^product.soldOut}}
                    <form action="/cart/add" method="post">
                        <input type="hidden" name="product_id" value="{{product.id}}">
                        <div class="quantity-selector">
                            <label for="quantity">{{#lang}}Quantity{{/lang}}</label>
                            <input type="number" name="quantity" value="1" min="1" id="quantity">
                        </div>
                        <button type="submit" class="btn-add-to-cart">
                            {{#lang}}Add to Cart{{/lang}}
                        </button>
                    </form>
                {{/product.soldOut}}
                
                {{#product.soldOut}}
                    <button class="btn-sold-out" disabled>
                        {{#lang}}Out of Stock{{/lang}}
                    </button>
                {{/product.soldOut}}
            </div>
        </div>
    </div>
</body>
</html>

Step 8: Test Your Template

1

Save your changes

Click Save in the theme editor

2

Preview the page

Use the preview function to see your changes on a test product

3

Test different scenarios

  • Products with/without images
  • Products with/without variants
  • Products that are in stock vs. sold out
4

Publish when ready

When you’re satisfied, publish your changes to make them live

🎉 Congratulations!

You’ve successfully created your first custom Quickbutik theme template! You now understand:

  • ✅ How to display product data dynamically
  • ✅ How to use conditionals for different states
  • ✅ How to handle product variants and options
  • ✅ How to create functional form elements

Next Steps

Common Issues