✨ Strapi MCP is now Generally Available - let your agents manage your Strapi content ✨

Ecommerce3 min read

Building an Ecommerce Website with Jekyll, Strapi, Snipcart and Tailwind CSS - 4 of 5

June 17, 2022Updated on May 22, 2026

Welcome to the fourth part of creating an eCommerce website with Strapi, Jekyll, Tailwind CSS, and Snipcart series. Before reading this, you should catch up on the first, second, and third parts of this tutorial series.

In this part of the series, we will be creating our product catalog and single product views.

Creating our Product Catalog

Fetching All Products

In the third part of our series, we learned how to make a GET request to the Strapi server from the Jekyll frontend using the Strapi-Jekyll plugin. We will be using the same process to make a GET request for our products in this step.

Add the following collection to the Strapi endpoint in your config.yml file.

       products:
         type: products

This code calls the endpoint that gets all our products from the Strapi backend.

Display All Products

Create a product.html file in your root folder. Add the following code snippets to the file.

        ---
        layout: default
        ---
        <div class="mt-6">
          <h1 class="flex justify-center text-gray-600 font-semibold text-5xl mb-10">
            Welcome to our store.
          </h1>
          {%- if strapi.collections.products.size > 0 -%}
          <div
            class="
              grid grid-cols-1
              gap-y-10
              sm:grid-cols-2
              gap-x-6
              lg:grid-cols-3
              xl:grid-cols-4
              xl:gap-x-8
            "
          >
            {%- for product in strapi.collections.products -%}
            <a
              key="{product.id}"
              href="/product{{ product.slug | relative_url }}"
              class="group mb-10"
            >
              <div
                class="
                  w-full
                  aspect-w-1 aspect-h-1
                  bg-gray-200
                  rounded-lg
                  overflow-hidden
                  xl:aspect-w-7 xl:aspect-h-8
                "
              >
                <img
                  src="http://localhost:1337{{ product.Image.url }}"
                  alt="{product.id}"
                  class="
                    w-full
                    h-60
                    object-center object-cover
                    group-hover:opacity-75
                  "
                />
              </div>
              <h3 class="text-center mt-4 text-sm text-gray-700">{{ product.name }}</h3>
              <p class="text-center mt-1 text-lg font-medium text-gray-900">
                ${{ product.price }}
              </p>
            </a>
            {%- endfor -%}
          </div>
          {%- endif -%}
        </div>

Again, as in the last part of our series, we used Liquid templating to loop through our products and Tailwind CSS to create a view for displaying the product.Also, we added the default layout in our frontmatter to apply our default layout to the page.

Access the product page by visiting http://localhost:4000/products. The page should look like this, depending on the types of products you added to your backend.

Creating Single Product Views

Fetching the Data for Single Products

To create a page for each product, we will need to create a collection for getting each product and displaying them on a page. Add the following collection to the Strapi endpoint in your config.yml file.

       product:
         type: products
         permalink: "/product/:slug/"
         layout: product.html
         output: true

What this collection does is that it gets a product and displays the product using the product.html layout. The permalink will serve as the link to the product page. Now, navigate to the _layouts folder and create a product.html file. Add the following lines of code to the product.html file.

        ---
        layout: default
        ---
         
        <div>
         <div
           class="
             mt-6
             max-w-2xl
             mx-auto
             sm:px-6
             lg:max-w-7xl
             lg:px-8
             lg:grid lg:grid-cols-3
             lg:gap-x-8
           "
         >
           <div
             class="hidden aspect-w-3 aspect-h-4 rounded-lg overflow-hidden lg:block"
           >
             <img
               src="http://localhost:1337{{ page.document.images[1].url }}"
               alt="{product.images[0].alt}"
               class="w-full h-full object-center object-cover"
             />
           </div>
           <div class="hidden lg:grid lg:grid-cols-1 lg:gap-y-8">
             <div class="aspect-w-3 aspect-h-2 rounded-lg overflow-hidden">
               <img
                 src="http://localhost:1337{{ page.document.images[2].url }}"
                 alt="{product.images[1].alt}"
                 class="w-full h-full object-center object-cover"
               />
             </div>
             <div class="aspect-w-3 aspect-h-2 rounded-lg overflow-hidden">
               <img
                 src="http://localhost:1337{{ page.document.images[3].url }}"
                 alt="{product.images[2].alt}"
                 class="w-full h-full object-center object-cover"
               />
             </div>
           </div>
           <div
             class="
               aspect-w-4 aspect-h-5
               sm:rounded-lg
               sm:overflow-hidden
               lg:aspect-w-3 lg:aspect-h-4
             "
           >
             <img
               src="http://localhost:1337{{ page.document.images[0].url }}"
               alt="{product.images[3].alt}"
               class="w-full h-full object-center object-cover"
             />
           </div>
         </div>
         <div
           class="
             max-w-2xl
             mx-auto
             pt-10
             pb-16
             px-4
             sm:px-6
             lg:max-w-7xl
             lg:pt-16
             lg:pb-24
             lg:px-8
             lg:grid lg:grid-cols-3 lg:grid-rows-[auto,auto,1fr]
             lg:gap-x-8
           "
         >
           <div class="lg:col-span-2 lg:border-r lg:border-gray-200 lg:pr-8"></div>
           <div class="mt-4 lg:mt-0">
             <h1
               class="flex justify-center mb-5 text-2xl font-extrabold tracking-tight text-gray-900 sm:text-3xl"
             >
               {{ page.document.name }}
             </h1>
             <p class="text-3xl flex justify-center text-gray-900">
               $ {{ page.document.price }}
             </p>
         
             <button
               type="submit"
               class="
                 mt-10
                 w-full
                 bg-blue-900
                 border border-transparent
                 rounded-md
                 py-3
                 px-8
                 flex
                 items-center
                 justify-center
                 text-base
                 font-medium
                 text-white
                 hover:bg-indigo-700
                 focus:outline-none
                 focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500
               "
             >
               Add to cart
             </button>
           </div>
           <div class="-mt-20 lg:pb-16 lg:col-start-1 lg:col-span-2 lg:border-r lg:border-gray-200 lg:pr-8">
             <div>
               <div class="space-y-6">
                 <p class="text-gray-900">{{ page.document.description }}</p>
               </div>
             </div>
         
             <div class="mt-10">
               <h2 class="text-lg font-bold text-gray-900">Details</h2>
         
               <div class="mt-4 space-y-6">
                 <p class="text-sm text-gray-600">{{ page.document.additional_information }}</p>
               </div>
             </div>
           </div>
         </div>
        </div>

What this code does is that it gives each product page the default layout, which was specified in the frontmatter. Since this layout is associated with numerous products, not one, we will be specifying the template name as the {{ page.document }} instead. This will allow all the products using the layout to take advantage of the layout. The product page should look like this, depending on the products you added to your backend server.

Sample Screenshot

Conclusion

In this part of the series, we created our product catalog and single product views. The next part of the series will be about implementing the cart functionality in our website with Snipcart.

Here are the links to the final source code: Frontend Repository & Backend Repository

Ecommerce·7 min read

Building an Ecommerce Website with Jekyll, Strapi, Snipcart and Tailwind CSS [1 of 5]

In part one, you will learn how to install Strapi, Jekyll, and Tailwind and set up the back-end.

·June 17, 2022
Ecommerce·2 min read

Building an Ecommerce Website with Jekyll, Strapi, Snipcart and Tailwind CSS - 2 of 5

In the second part of the tutorial series, learn how to create the Website’s Layout.

·June 17, 2022
Ecommerce·4 min read

Building an Ecommerce Website with Jekyll, Strapi, Snipcart and Tailwind CSS - 3 of 5

In the third part of this series, learn how to create the homepage hero.

·June 17, 2022