Sign in
Log inSign up
Jekyll E-Commerce Tutorial: Add a Shopping Cart to Your Static Website

Jekyll E-Commerce Tutorial: Add a Shopping Cart to Your Static Website

Michael Poirier-Ginter's photo
Michael Poirier-Ginter
·Aug 30, 2019

The last version of this post dated back to 2016. Since then SSGs have changed, Jekyll has changed, Snipcart has changed; so let’s take a fresher look at how to use Jekyll for e-commerce! Lucky for us, Jekyll just released a new version this week, which we used for this demo.


Like many devs, one of our first encounters with static site generators came through the discovery of Jekyll.

It was back in 2015.

Jekyll was dominating the field at that time, and we remember loving it from the get-go.

Even though it has more competition than ever, you can still see Jekyll sitting at the top of the list of popular SSGs.

Today, I want to explore Jekyll for one specific use case: e-commerce.

So after going through this SSGs’ basics and why it’s a good option for e-commerce projects, I’ll show you how to build a fully functioning Jekyll shop.

Tutorial steps 🛠

  • Installing Ruby & Jekyll
  • Creating a collection
  • Overriding Jekyll’s default theme
  • Integrating a shopping cart
  • Deploying a Jekyll e-commerce website

Let’s do this!

What is Jekyll?

jekyll

Jekyll is GitHub co-founder Tom Preston-Werner's popular Ruby open source program. It prompts developers to transform your plain text into static websites and blogs. Jekyll is the engine behind GitHub Pages, which you can use to host sites right from your GitHub repositories.

The philosophy behind it?

Jekyll does what you tell it to do — no more, no less. It doesn't try to outsmart users by making bold assumptions, nor does it burden them with needless complexity and configuration. Put simply, Jekyll gets out of your way and allows you to concentrate on what truly matters: your content.

In a way, Jekyll is like tofu, you know? It only tastes what you want to make out of it, nothing more, nothing less. The choice of ingredients (plugins, third-party services) to arrive at a final recipe is all up to you. It can appear like a limitation for some, but it actually is Jekyll’s greatest strength if you know what you’re doing.

How does it accomplish this? By taking your content, rendering Markdown and Liquid templates, and spitting out fully static websites ready to be served by a CDN.

how-jekyll-works

Version 4.0 was released just a few days ago. Faster build times, faster Sass support, and better optimizations are at the center of this latest update. Luckily for us, it was released just in time to use it for this demo.

Jekyll is mainly associated with blogs and small personal website, so it would be legitimate to have concerns when it comes to using it for e-commerce. Let's address those concerns.

Jekyll for e-commerce: a good fit?

jekyll-ecommerce-good-fit

One thing that is important to remember is that Jekyll is content-focused, stripping the website development process from unnecessary hassles. It brings a real limitation when it comes to project size.

Over a certain number of products and pages on your website, you’d probably be better off looking at the more fully-featured SSGs that are Gatsby, Next.js or Nuxt. However, for a small e-commerce project with only a few products? Jekyll is great. That’s precisely what we’re going to do in the demo below.

Here are a few benefits you get by using Jekyll:

→ Fast & secure

A Jekyll website is going to be way faster and more secure than the most optimized WordPress instance. These are actually selling points for the JAMstack as a whole. Because your website is only static files served to a client by a CDN, the need for server calls is abstracted, hence better performance. You also limit the attack surface for potential hacks.

→ SEO baked in

Search Engine Optimization is crucial to the success of any e-commerce website. Jekyll will never get in the way search bots when crawling your pages, them being mostly static HTML files. Plus, the good performances I mentioned in the first point are also a ranking factor in Google.

→ Popularity & active community

Need advanced functions for your Jekyll website? Chances are there is a plugin to answer your needs. It has been one of the most popular static site generators for many years now and has gathered a considerable following along the way. Help will always be just a Google search away.

By default, your content lives in GitHub. Depending on your needs, you could connect your Jekyll project to a headless CMS. If the content is going to be managed by non-technical users, it might simplify the workflow for them. We’ve crafted this guide to headless e-commerce if you want to know more about it.

Technical Tutorial: Build a Jekyll E-Commerce Website with Snipcart

jekyll-ecommerce

Prerequisites

1. Installing Ruby

Since Jekyll is a Ruby Gem, you'll need to install Ruby on your development environment. Doing so will differ significantly depending on your operating system. You can, therefore, refer to Jekyll's official documentation for this part.

Also, if you're not familiar with Ruby, you might want to check out Jekyll's Ruby 101 guide if you haven't already!

2. Installing Jekyll

Once you've successfully installed a full Ruby development environment, you can install Jekyll and Bundler with this command:

gem install jekyll bundler

2.1 Creating and serving a new Jekyll project

Now that your development environment is ready to go, you can create your new project using Jekyll's CLI.

jekyll new snipcart-jekyll

At this stage, you might notice that your project directory looks a bit empty. This is because ever since Jekyll 3.2, themes are gem-based by default and can be found outside your project's directory. I'll talk more about this later on when we override the default theme, minima.

Now, to serve your project, use the following command and visit localhost:4000 in your browser.

bundle exec jekyll serve

3. Creating a new collection

Let's start by creating a collection for your store that will contain all of the products. A collection is simply a type of content that is available in Jekyll.

To create this collection, add this code snippet at the end of your _config.yml file and serve your project again.

collections:
 - products

If you’re unsure as to why we're using collections rather than pages, or posts, you should check out this article. It helped me to understand the various types of content that are available in Jekyll.

3.1 Adding content to a collection

Now that your collection is registered in your project's configuration, you can create a new directory in the root of your project named _products. This directory will store all the content of your collection.

Let’s say I'm creating a store selling painting replicas, I created a new markdown file named product1.md with the following code.

---
identifier: jekyll-starry-night
name: Starry Night
price: 79.95
image: /assets/images/starry-night.jpg
**---**
This is a high-quality replica of The Starry Night by the Dutch post-impressionist painter Vincent van Gogh. Using brand new techniques such as magneto-reluctance and capacitive reactance, we were able to reproduce the original colours with a 99.99% accuracy.

Notice that, unlike traditional markdown, this file also contains a front matter, added at the beginning between a pair of dashes. Inside this front matter, you can define some predefined or custom variables. In this case, you’ll use it to store information about the product that you'll then use in the templates to render Snipcart's product definition.

Also, make sure the names of your custom variables aren't sharing the same namespace as Jekyll's predefined variables. This is the reason I used the term identifier rather than id.

4. Overriding the default theme

As explained earlier, the project came bundled with Jekyll's official theme, minima. Unfortunately, this theme currently doesn't fit the needs of an e-commerce store.

Therefore, you can override the theme with your own. Since the default theme is a gem-based, there are multiple ways to go about this. However, since I like having all my files in my project's directory, I'll simply copy and paste all of the theme's files inside my project and modify the configuration of my project.

If you also wish to do so, you can locate the theme's path with this bundle command:

bundle show minima

Then, transfer over all of the files (except the readme and licence) over to the root of your local project.

Once this is completed, you'll need to specify these changes in your configuration file and Gem file.

Head over to your _config.yml and comment out or remove this line:

theme: minima

Also, comment out or remove any minima reference in your Gemfile.

gem "minima", "~> 2.0"

You can now run bundle update and serve your project again using the local theme.

5. Adding e-commerce to your Jekyll website

Now that you can modify your template, you can add Snipcart to the project.

Open the file header.html file and include Snipcart's stylesheet inside the head tag:

<head>
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <title>{% if page.title %}{{ page.title | escape }}{% else %}{{ site.title | escape }}{% endif %}</title>
 <meta name="description" content="{{ page.excerpt | default: site.description | strip_html | normalize_whitespace | truncate: 160 | escape }}">
 <link rel="stylesheet" href="{{ "/assets/main.css" | relative_url }}">
 <link rel="stylesheet" href="cdn.snipcart.com/themes/v3.0.0-beta.3/defa…" />
 <link rel="canonical" href="{{ page.url | replace:'index.html','' | absolute_url }}">
</head>

It’s also worth noting that I've taken the liberty to remove things I didn't need from the original theme, such as the Google Analytic's code snippet. Leave it in there if it’s something you’d like to use.

Now, open up the default.html file in the _layout directory and add the rest of the required asset's.

<!DOCTYPE html>
<html lang="{{ page.lang | default: site.lang | default: "en" }}">
{% include head.html %}
<body>
 {% include header.html %}
 <main class="main">
 <div class="products">
 {{ content }}
 </div>
 </main>
 {% include footer.html %}
</body>
<div hidden id="snipcart" data-api-key="<your_api_key>"></div>
<script src="cdn.snipcart.com/themes/v3.0.0-beta.3/defa…" defer></script>
</html>

Don't forget to change the data-api-key attribute with your own API key, provided in Snipcart’s dashboard.

5.1 Creating templates for products and buy buttons

Create a product-defintion.html file inside the _includes directory that will display Snipcart's product definition.

<button
 class="buy-button snipcart-add-item"
 data-item-id="{{ product.identifier }}"
 data-item-name="{{ product.name }}"
 data-item-price="{{ product.price }}"
 data-item-image="{{ product.image }}"
 data-item-url="snipcart-jekyll.netlify.com{{ page.url }}"
 data-item-description="{{ product.content | remove: '<p>' | remove: '</p>' }}">
 Add to cart (${{ product.price }})
</button>

Also, create a product.html file inside the same directory that will display the relevant information about your product and include the product definition.

<div class="product">
 <div class="product__information">
    <h2 class="product__title">{{ product.name }}</h2>
    <p class="product__description">{{ product.content | remove: '<p>' | remove: '</p>' }}</p>
    {% include product-definition.html %}
 </div>
 <img src="{{ product.image }}" alt="{{ product.name }} product image" class="product__image">
</div>

You're going to make use of these templates in the next step when displaying the products on the home page. Obviously, you can customize these to your liking if you wish.

Also, noticed how I used the remove '<p>' and remove </p> tag for the product description?

This is because, by default, Jekyll will wrap the markdown content inside a <p> tag. Thankfully the Liquid templating engine comes with many helpful utilities to prevent this.

5.2 Displaying products on the homepage

Now that Snipcart is installed on your website and ready to go, you can add this code Snippet inside your index.markdown page.

---
layout: default
---
{% for product in site.products %}
 {% include product.html %}
{% endfor %}

Since the default.html page displays the content of the markdown page using {{ content }}, you can loop through your collection using the site variable and include the product.html template for each product.

6. Deploying your Jekyll e-commerce website

Once you're satisfied with your site, you'll probably want to put it online. There are many excellent solutions when it comes to deploying and hosting a statically generated sites such as Netlify, GitHub Pages and many more.

Here, I'll show you how to deploy your site using Netlify. Jekyll's documentation has already thoroughly explained how to achieve this using GitHub Pages.

To do so, you'll need to put your project on GitHub, GitLab or BitBucket. Once this is done, hosting your site using Netlify is as easy as logging in and linking your repository.

Usually, Netlify will be able to detect that you're creating a Jekyll project and set up the following configuration automatically:

jekyll-site-deploy

That's it! Once the build is finished, your static e-commerce store should be live and ready to go!

Live demo & GitHub repo

jekyll-ecommerce-demo

See the Github repo here.

See the live demo here.

Closing thoughts

All in all, working with Jekyll was quite enjoyable.

I got a bit frustrated at first trying to set up my development environment as I previously already had an older version of Ruby installed using a package manager. Thankfully, all it took to get the ball rolling was a reinstall of Ruby. I also struggled a bit while overriding the theme to my liking. Perhaps I’m simply not familiar enough with the Ruby environment, but I think having the theme as a Gem by default adds a bit of complexity to get started quickly.

Otherwise, it’s still a speedy way to build & go live with a small e-commerce project.

I spent about a little more than a day to build this integration, but much time was wasted trying to get Ruby working on my computer (it happens!). If I were to repeat the experiment, it would probably only be a matter of a few hours.

Any questions? Feel free to hit comments to give us your thoughts, feedback, and questions. If you enjoyed this post, take a second to 👏 or share on Twitter!

Originally published on the Snipcart blog and in our newsletter.