Jekyll E-commerce with Snipcart: Add a Shopping Cart to Your Static Site
Learn how to add a fully functional shopping cart to a Jekyll site using Snipcart. Product listings, checkout, payments, and order management — no backend required.
Jekyll is a static site generator — it does not have a database, a server, or a shopping cart. But that does not mean you cannot sell online. Snipcart is a JavaScript-powered shopping cart that adds to any static site with a few lines of HTML. No backend, no database, no hosting complexity.
Here is how to build a fully functional Jekyll store with Snipcart.
What is Snipcart?
Snipcart is a headless e-commerce platform. You add their JavaScript to your site, mark your products with HTML data attributes, and Snipcart handles the cart, checkout, payment processing (via Stripe), and order management through their dashboard.
You keep full control of your site’s design. Snipcart handles everything that requires a server.
Pricing: 2% transaction fee on sales up to $500/month, then $20/month flat fee. Free to test with a sandbox mode.
Setting up Snipcart in Jekyll
Step 1: Create a Snipcart account
Sign up at snipcart.com. You will get a public API key for testing (sandbox) and one for production.
Step 2: Add Snipcart to your Jekyll layout
Add the following to your _layouts/default.html before the closing </body> tag:
{% if site.snipcart_key != "" %}
<link rel="preconnect" href="https://app.snipcart.com">
<link rel="preconnect" href="https://cdn.snipcart.com">
<link rel="stylesheet" href="https://cdn.snipcart.com/themes/v3.3.3/default/snipcart.css" />
<div hidden id="snipcart" data-api-key="{{ site.snipcart_key }}"></div>
<script async src="https://cdn.snipcart.com/themes/v3.3.3/default/snipcart.js"></script>
{% endif %}
Step 3: Add your API key to _config.yml
# _config.yml
snipcart_key: "" # Add your Snipcart public API key here
Keep your test key for local development and your live key in your hosting platform’s environment variables.
Step 4: Define products in front matter
Create a _products collection in _config.yml:
collections:
products:
output: true
permalink: /shop/:slug/
Create a product file at _products/jekyll-starter-theme.md:
---
layout: product
title: "Jekyll Starter Theme"
price: 29.00
sku: "JST-001"
description: "A clean, minimal Jekyll theme for developers. Includes dark mode, SEO optimisation, and full documentation."
image: /assets/images/products/jekyll-starter-theme.jpg
category: Themes
in_stock: true
---
Your full product description here in Markdown...
Step 5: Create the Add to Cart button
In your product layout or product listing, add a button with Snipcart’s data attributes:
<button
class="snipcart-add-item btn btn--primary"
data-item-id="{{ product.sku }}"
data-item-name="{{ product.title }}"
data-item-price="{{ product.price }}"
data-item-url="{{ product.url | absolute_url }}"
data-item-description="{{ product.description | strip_html | truncate: 255 }}"
data-item-image="{{ product.image | absolute_url }}"
>
Add to Cart — ${{ product.price }}
</button>
The data-item-url must point to the live product page where Snipcart can verify the price. This is Snipcart’s anti-fraud mechanism — it crawls the URL and confirms the price matches what was passed to the cart.
Step 6: Add the cart button to your nav
<button class="snipcart-checkout navbar__icon-btn" aria-label="Shopping cart">
<svg width="20" height="20" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 3h2l.4 2M7 13h10l4-8H5.4M7 13L5.4 5M7 13l-2.293 2.293c-.63.63-.184 1.707.707 1.707H17m0 0a2 2 0 100 4 2 2 0 000-4zm-8 2a2 2 0 11-4 0 2 2 0 014 0z"/>
</svg>
<span class="snipcart-items-count">0</span>
</button>
The snipcart-items-count class is updated automatically by Snipcart with the current cart item count.
Creating a product listing page
Create _pages/shop.html:
---
layout: default
title: "Shop"
permalink: /shop/
---
<div class="product-grid">
{% for product in site.products %}
<div class="product-card">
<img src="{{ product.image | relative_url }}" alt="{{ product.title }}">
<h3>{{ product.title }}</h3>
<p>{{ product.description | truncate: 120 }}</p>
<p class="price">${{ product.price }}</p>
<button
class="snipcart-add-item btn btn--primary"
data-item-id="{{ product.sku }}"
data-item-name="{{ product.title }}"
data-item-price="{{ product.price }}"
data-item-url="{{ product.url | absolute_url }}"
data-item-description="{{ product.description | strip_html | truncate: 255 }}"
data-item-image="{{ product.image | absolute_url }}"
>
Add to Cart
</button>
</div>
{% endfor %}
</div>
Handling digital products
Snipcart supports digital product delivery via a file URL. Add it to your button:
data-item-file-guid="YOUR_FILE_GUID"
You upload the file in the Snipcart dashboard and get a GUID. Snipcart delivers a download link to the customer after payment. This is ideal for selling theme files, ebooks, or templates.
Tax and shipping
Configure tax rules and shipping rates in the Snipcart dashboard — no code changes needed. You can set rates by country, region, or product category.
Alternatives to Snipcart
| Option | Best for |
|---|---|
| Snipcart | Most Jekyll stores — simplest setup |
| Gumroad | Digital products only — embed a Gumroad button |
| Stripe Payment Links | Single products, no cart needed |
| Shopify Buy Button | Larger catalogues with existing Shopify store |
| Lemon Squeezy | SaaS products, subscriptions, software |
Is Jekyll right for e-commerce?
Jekyll works well for stores with a small to medium catalogue (under a few hundred products), digital goods, or marketplaces where the product pages are mostly static content. It is not the right choice for large catalogues with complex inventory management, real-time stock levels, or customer accounts.
For selling a Jekyll theme or digital download, Jekyll plus Snipcart is a perfectly reasonable stack. For a 10,000-SKU physical goods store, reach for Shopify.