tetchi blog

Tetchi's blog about life and stuff

Shopify Theme from Scratch Part 2: index.liquid

Shopify Theme from Scratch – setting up the index.liquid template and creating our first snippet.


The index.liquid template loads the contents of the very first page that the customer sees when they enter the URL of your shop.

Away we go!

1. Add the contents of the Welcome page

The first thing we’re going to do is load the contents of the default Welcome page inside index.liquid.

default welcome page

Figure 2.1: By default, all shops come with a page called “Welcome” with the handle “frontpage”

Remove the “this is my index page!” text, and insert this line of code:

{% assign page = pages.frontpage %}

The assign statement tells the index.liquid template “from now on, every instance of the word ‘page’ in Liquid tags should be seen as ‘pages.frontpage'”. In other words, we’re telling index.liquid to look at a specific page in Blogs & Pages; otherwise it wouldn’t know which page to load.

page handle

Figure 2.2: You can see what a handle of a page is by looking under “URL and handle”

Next we’re going to add the page’s title and content. Add the code in red below.

{% assign page = pages.frontpage %}

{{ page.title }}

{{ page.content }}

If we didn’t have the assign statement, our code would look like this:

{{ pages.frontpage.title }}

{{ pages.frontpage.content }}

… and that’s a lot of extra typing. Not only that, if you decide to change what page is shown on the homepage, you’d have to change every instance of the handle. If you use an assign statement, you only need to change it once.

Note: When you target a page, always use the “handle” of the page. You could technically use the title of the page, but it’s always best to use the handles because handles are always unique. You may get unfavourable results if you use the title, and you happen to have two pages with the title “Welcome”. This also applies to products, collections, and anything with handles.

At this point, you should be seeing the contents of the “Welcome” page output on your homepage.

part2 progress1

2. Display products on the homepage

To start, we’re going to create a snippet that outputs products’ thumbnails. Snippets are bits of code that can be referenced in other templates of a theme. It’s handy for elements of a theme that is used repeatedly, because you just have to reference the snippet once as opposed to having to type out the code multiple times. They can also be used for organizational purposes (ex: if you have a big chunk of code, you may want to store it in a snippet instead of taking up a bunch of lines in your tempate). Snippets always reside in the “Snippets” folder of your Template Editor.

Later we can use the “product-loop.liquid” snippet that we’ll be creating here on our collection pages to output product thumbnails there. Recycling FTW!

How to create a snippet:

If you’re using the Desktop Theme Editor like I am, you can simply create a new file called “product-loop.liquid”, and place it in the snippets folder.

making product loop

An exciting picture of me creating a snippet in Textmate

If you’re using the Template Editor, simply click the “Add a new snippet” link, enter “product-loop” for its name, and hit the “Create Snippet” button. Refer to Figure 2.3 below if you’re unsure where that is.

adding a snippet

Figure 2.3: Adding a snippet in Shopify’s Template Editor

Putting product-loop.liquid to use

Let’s go ahead and add the code to load the product-loop.liquid snippet. Open index.liquid and add the code in red below.

{% assign page = pages.frontpage %}

{{ page.title }}

{{ page.content }}
{% assign collection = collections.frontpage %}

{{ collection.title }}

{% for product in collection.products | limit:8 %} {% include 'product-loop' %} {% endfor %}

Now, this won’t actually output anything yet except for the collection title, because our product-loop.liquid snippet is still blank. What we’re doing above is we’re first assigning “collection” to be “collections.frontpage”, much like we did with the Welcome page in step 1. The Frontpage collection is a default collection that comes with every shop, and in Part 1 we added products to it (you should have 9 products in the Frontpage collection now).

After that, we do a for-loop to go through each product in the Frontpage collection and outputting the product-loop snippet for every product in it. There is also a “limit” filter with a value of 8 so that we only show the first 8 products in the Frontpage collection. I put that in there because I wanted there to be an even 4 products per row.

Build the product-loop snippet

Open the “product-loop.liquid” snippet. Let’s start off by adding the following code:

This will be the div that wraps each of our products. The cycle tag is a cool feature that you can use inside for-loops that lets you output something every n-th iteration of a forloop. More info on the cycle tag can be found here. In this instance, I’m going to be applying a CSS class called “last” for every fourth product so that I can target the last product in every row. Then, I’m going to use the “last” class to apply some special styles to it later.

Let’s go ahead and add the code for the product image, title, and price. Insert the code in red below:

{% if product.price_varies %}From{% endif %} {{ product.price | money }}

Essentially here I am using the variables available in the product object and outputting them accordingly.

Pretty it up with CSS

Open style.css. At the bottom, add the following CSS:

/**** product-loop.liquid ****/

.product{margin:0 20px 30px 0; width:225px; text-align:center; font-weight:bold;}
.product-thumb{border:1px solid #ccc; padding:10px;}
.product-thumb img{max-width:100%; height: auto;}
.product-title{ margin-top:10px;}

This will make the product-loop snippet look nicer, but notice that the product thumbnails are currently stacked on top of each other.

stacked images

Figure 2.4: The products are not being floated, so they will stack on top of each other.

We’re going to to fix this up by “floating” the thumbnails to each other. Still inside style.css, scroll up to the global.css section and insert the following CSS code in red. We’re going to add some classes for floating elements, as well as a class called ‘clearfix’.

/**** global css ****/

body{font-family:Arial, Helvetica, sans-serif;}
a {text-decoration:none; color:#5fa6d8;}

.left{float: left;}
.right{float: right;}
.last{margin-right:0px !important;}

/* Contain floats: nicolasgallagher.com/micro-clearfix-hack/ */ 
.clearfix:before, .clearfix:after { content: ""; display: table; }
.clearfix:after { clear: both; }
.clearfix { zoom: 1; }

/**** theme.liquid ****/

.container{width: 960px; margin: 0 auto;}

Clearfix is a technique used to “clear” elements on a page. I won’t go too far into the details, but when you’re laying things out with CSS, you typically “float” elements left or right. When you float elements, you need to “clear” them afterwards.

If you don’t clear elements that are being floated, you’re gonna have a bad time. Your layout will likely break.

bad time

Figure 2.5: The product-loop sans clearfix. Notice how the footer is collapsing in to the product-loop.

Your index page should look like this now:

part2 progress2

That’s all for today :)

← Back to table of contents


  • John
    John on November 24th, 2014


    Thanks for the great resource! Very helpful!

    Could you clarify which CSS classes are necessary and which aren’t? For instance, the .rte class I believe is generally for rich text input from the user. However, I didn’t see any .rte class in the css files for this template. Is there some other reason for including it (e.g. they are accessed by the Shopify scripts)? There are other CSS classes here that present the same question like index-page and index-collection. Could you please clarify?

    Also, generally, are there any CSS classes that are absolutely required for Shopify to work properly?

  • Carl
    Carl on April 10th, 2015

    Thank you so much for this tutorial! I’m learning a lot.

    One problem though… I’m not able to get the the thumbnails to “float” next to each other. I pasted the code to no change on my page ( the thumbnails are still stacked on top of each other ). Is there something new that needs to be done? My code is exactly the same as yours.

  • Carl
    Carl on April 10th, 2015

    Fixed it.

    It looks like Shopify renamed my style.css and normalize.css files to have the .liquid ending. I renamed the file on my computer to have the .liquid ending and everything snapped into shape!

  • Jonny
    Jonny on August 3rd, 2015

    Followed this to the letter so far but my homepage products wont display on two rows of 4. Its showing as two rows of three and one row of two. I get this error prompt on my index.liquid screen:

    The following were flagged as potential issues in this file:
    Line 9 — Liquid syntax error: Expected end_of_string but found pipe in “product in collection.products | limit:8”
    These issues may not affect your theme, but should be reviewed if you notice any problems.
    Note: This message is only shown in development shops.

    Any help?

Post a comment