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.
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.
1 products:
2 type: products
This code calls the endpoint that gets all our products from the Strapi backend.
Create a product.html
file in your root folder. Add the following code snippets to the file.
1 ---
2 layout: default
3 ---
4 <div class="mt-6">
5 <h1 class="flex justify-center text-gray-600 font-semibold text-5xl mb-10">
6 Welcome to our store.
7 </h1>
8 {%- if strapi.collections.products.size > 0 -%}
9 <div
10 class="
11 grid grid-cols-1
12 gap-y-10
13 sm:grid-cols-2
14 gap-x-6
15 lg:grid-cols-3
16 xl:grid-cols-4
17 xl:gap-x-8
18 "
19 >
20 {%- for product in strapi.collections.products -%}
21 <a
22 key="{product.id}"
23 href="/product{{ product.slug | relative_url }}"
24 class="group mb-10"
25 >
26 <div
27 class="
28 w-full
29 aspect-w-1 aspect-h-1
30 bg-gray-200
31 rounded-lg
32 overflow-hidden
33 xl:aspect-w-7 xl:aspect-h-8
34 "
35 >
36 <img
37 src="http://localhost:1337{{ product.Image.url }}"
38 alt="{product.id}"
39 class="
40 w-full
41 h-60
42 object-center object-cover
43 group-hover:opacity-75
44 "
45 />
46 </div>
47 <h3 class="text-center mt-4 text-sm text-gray-700">{{ product.name }}</h3>
48 <p class="text-center mt-1 text-lg font-medium text-gray-900">
49 ${{ product.price }}
50 </p>
51 </a>
52 {%- endfor -%}
53 </div>
54 {%- endif -%}
55 </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.
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.
1 product:
2 type: products
3 permalink: "/product/:slug/"
4 layout: product.html
5 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.
1 ---
2 layout: default
3 ---
4
5 <div>
6 <div
7 class="
8 mt-6
9 max-w-2xl
10 mx-auto
11 sm:px-6
12 lg:max-w-7xl
13 lg:px-8
14 lg:grid lg:grid-cols-3
15 lg:gap-x-8
16 "
17 >
18 <div
19 class="hidden aspect-w-3 aspect-h-4 rounded-lg overflow-hidden lg:block"
20 >
21 <img
22 src="http://localhost:1337{{ page.document.images[1].url }}"
23 alt="{product.images[0].alt}"
24 class="w-full h-full object-center object-cover"
25 />
26 </div>
27 <div class="hidden lg:grid lg:grid-cols-1 lg:gap-y-8">
28 <div class="aspect-w-3 aspect-h-2 rounded-lg overflow-hidden">
29 <img
30 src="http://localhost:1337{{ page.document.images[2].url }}"
31 alt="{product.images[1].alt}"
32 class="w-full h-full object-center object-cover"
33 />
34 </div>
35 <div class="aspect-w-3 aspect-h-2 rounded-lg overflow-hidden">
36 <img
37 src="http://localhost:1337{{ page.document.images[3].url }}"
38 alt="{product.images[2].alt}"
39 class="w-full h-full object-center object-cover"
40 />
41 </div>
42 </div>
43 <div
44 class="
45 aspect-w-4 aspect-h-5
46 sm:rounded-lg
47 sm:overflow-hidden
48 lg:aspect-w-3 lg:aspect-h-4
49 "
50 >
51 <img
52 src="http://localhost:1337{{ page.document.images[0].url }}"
53 alt="{product.images[3].alt}"
54 class="w-full h-full object-center object-cover"
55 />
56 </div>
57 </div>
58 <div
59 class="
60 max-w-2xl
61 mx-auto
62 pt-10
63 pb-16
64 px-4
65 sm:px-6
66 lg:max-w-7xl
67 lg:pt-16
68 lg:pb-24
69 lg:px-8
70 lg:grid lg:grid-cols-3 lg:grid-rows-[auto,auto,1fr]
71 lg:gap-x-8
72 "
73 >
74 <div class="lg:col-span-2 lg:border-r lg:border-gray-200 lg:pr-8"></div>
75 <div class="mt-4 lg:mt-0">
76 <h1
77 class="flex justify-center mb-5 text-2xl font-extrabold tracking-tight text-gray-900 sm:text-3xl"
78 >
79 {{ page.document.name }}
80 </h1>
81 <p class="text-3xl flex justify-center text-gray-900">
82 $ {{ page.document.price }}
83 </p>
84
85 <button
86 type="submit"
87 class="
88 mt-10
89 w-full
90 bg-blue-900
91 border border-transparent
92 rounded-md
93 py-3
94 px-8
95 flex
96 items-center
97 justify-center
98 text-base
99 font-medium
100 text-white
101 hover:bg-indigo-700
102 focus:outline-none
103 focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500
104 "
105 >
106 Add to cart
107 </button>
108 </div>
109 <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">
110 <div>
111 <div class="space-y-6">
112 <p class="text-gray-900">{{ page.document.description }}</p>
113 </div>
114 </div>
115
116 <div class="mt-10">
117 <h2 class="text-lg font-bold text-gray-900">Details</h2>
118
119 <div class="mt-4 space-y-6">
120 <p class="text-sm text-gray-600">{{ page.document.additional_information }}</p>
121 </div>
122 </div>
123 </div>
124 </div>
125 </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.
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