As the latest dev hire for Snipcart, I was put to the test quickly.
My mission? Craft an e-commerce side-project using our shopping cart with an imposed technology, in a limited amount of time.
The technology in question? Gridsome, the Jamstack framework for Vue.js.
So, I rolled up my sleeves and got to work.
My efforts resulted in a Gridsome e-commerce demo. I documented my process in a step-by-step tutorial ready for you to follow along.
This tutorial explores how to:
Create a Gridsome project
Enable e-commerce functionalities with Snipcart
Craft product listings & pages
Configure the template routing
Leverage GraphQL with Gridsome
I think I did a decent job. Let’s see, shall we?
What’s up with Gridsome?
In case you don’t know about it, Gridsome is a modern website generator for Vue.js.
What does “modern” mean here? As a tool, it falls under the trending Jamstack umbrella and can be used to generate static websites, progressive web apps (PWA), or single-page apps (SPA). Whatever the type of frontend platform you want to create, Gridsome makes it easy to connect to any CMS or data source using GraphQL.
This first post we wrote about Gridsome explained how to use the GraphQL API to fetch data from an Airtable database.
Familiar with the React-powered Gatsby? Well, Gridsome can be considered the equivalent for Vue.
Their latest major release was Gridsome v0.7, which enables Vue components in Markdown, a new schema API, better template configuration & file-based dynamic routing.
I would recommend basic knowledge about HTML, CSS, and Vue.js before jumping into Gridsome. However, don’t be scared by it if you’re not a GraphQL expert; Gridsome is actually a great way to learn it.
Why use Gridsome for your e-commerce projects?
Since e-commerce is the specific use case concerning us here, let’s see what benefits Gridsome can bring to this kind of project.
→ Fast by default - With e-commerce, UX is everything. You don’t want customers stuck in front of a loading page for too long. At the risk of sounding like a broken record, one of the main benefits of the Jamstack is performance. Gridsome is no exception. With features like code splitting, asset optimization & progressive images out of the box, speed is taken care of!
→ SEO-Friendly - A well-optimized online shop can give you an edge over your competition. If performance is already a big plus for SEO, you also want search engines to crawl your pages content fully. By loading pages as static HTML before converting them into Vue-powered SPAs, Gridsome does just that.
→ PWA-ready - Want to push customer experience even further? Consider going the PWA route, enabling reload-free offline shopping. We’ve explored PWA e-commerce in-depth in this post.
→ Plugins for dynamic features - When your e-commerce project scales, you might need more dynamic functions to handle users’ shopping needs. Gridsome already offers an array of plugins to expand your website’s functionalities. There’s a straight-up Shopify plugin available that might fit your needs if you prefer using something else than Snipcart!
However, it’s also easy to opt for a third-party shopping cart integration with Gridsome. That’s precisely what I’ll do in the tutorial below, plugging our HTML/JS shopping cart into a static website.
Let’s do this!
Build an e-commerce website using Snipcart and Gridsome
1. Set up the development environment
To manage your Gridsome project, install Gridsome CLI globally by using the following command in a terminal:
npm install --global @gridsome/cli
2. Create a Gridsome project
To create your project, use the following command:
gridsome create snipcart-gridsome
Now go to the project directory:
cd snipcart-gridsome
And start the local server:
gridsome develop
A starter project should now be visible at the specified port in your terminal. You’re now ready to code!
3. Add Snipcart assets
Let's first install Snipcart by overriding Gridsome default index.html and add the required assets in the index.html file.
By following our installation documentation, you should have added the preconnect hints and stylesheet link in the <head>. You should also have the snipcart div (<div id="snipcart">) and the script tag in the <body> of the file.
Your index.html file should now look like this (do not forget to change YOUR_PUBLIC_API_KEY for the correct value):
Let's now add your store checkout in your website's header.
4. Add Snipcart checkout and user profile buttons in your website's header
With Snipcart installed, you can now add buttons that will interact with the cart.
4.1 Add checkout button
Open the Default.vue file in the layout folder. Code in this file will be used by all pages by default so this is where you can add a menu, for example. Somewhere in this file, add a button with the snipcart-checkout class on it:
<button class="snipcart-checkout">
Cart
</button>
Snipcart will react to a click on any element with the snipcart-checkout class by opening the cart.
Now, test if Snipcart checkout opens when you click on the link you just added.
Let's also display the number of items currently in the cart and their total price. Nested in your button element, add span elements with, respectively, the snipcart-items-count and snipcart-total-price classes binded:
Snipcart will automatically update these <span> tags with the current value. To customize the display of the price, you can obtain the cart total price by following those few next steps.
Add a totalPrice attribute and a getTotalPrice method in the component script section main object in the Default page:
Before populating the cart summary with your totalPrice data attribute, add the following custom filter in main.js. It will allow you to format the returned number as a currency:
Vue.filter("formatMoney", function (number) {
const formatter = new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
minimumFractionDigits: 2,
});
return formatter.format(number);
});
Combine the filter with the getTotalPrice method you just created to populate the cart's summary:
Like the checkout button, Snipcart will detect clicks on this button and open the customer profile view.
Now that Snipcart is integrated, you are ready to add products to your store.
5. Add a mock product list
In order to integrate products into your component, you need actual product data. Let's make some.
Create a folder named services. In this folder, create a file named productApi.js.
Then, make a getProducts function that will return an array of products:
const getProducts = () => {
return [
{
id: 1,
name: "Blinky",
images: {
small: "blinky-small.png",
big: "blinky-big.png",
},
descriptions: {
short: "Pack leader",
long:
"Natural leader. Gets a speed boost when pack pellets are cleared.",
},
price: 1337,
url: "/products/1",
},
{
id: 2,
name: "Inky",
images: {
small: "inky-small.png",
big: "inky-big.png",
},
descriptions: {
short: "Hungover but swift",
long:
"Had a big night yesterday, but brace yourself, he is still pretty fast.",
},
price: 3141,
url: "/products/2",
},
{
id: 3,
name: "Pinky",
images: {
small: "pinky-small.png",
big: "pinky-big.png",
},
descriptions: {
short: "Natural ambusher",
long: "Natural ambusher. Will cut you off. Be careful when you turn!",
},
price: 2718,
url: "/products/3",
},
{
id: 4,
name: "Clyde",
images: {
small: "clyde-small.png",
big: "clyde-big.png",
},
descriptions: {
short: "Got chaotic moves",
long: "moves = Math.random() * Math.floor(10000000)",
},
price: 1235,
url: "/products/4",
},
];
};
exports.getProducts = getProducts;
Ultimately, you’ll be able to change the function body to call your own product API and return the results. For now, let's add our data to Gridsome's built-in GraphQL server.
6. Add the data to a Gridsome collection
In the gridsome.server.js file, import the product API file:
Let's look at what’s happening here: after creating a new Product collection and assigning mock products to the data variable, we loop through these products, adding a newly created node to our product collection with mapped attributes of each product.
The collection should now be available through our local Gridsome GraphQL server. It's time to display products!
7. Make your store's product page
In the templates folder, create a Product.vue file. This file will be your product template. In Gridsome, templates are used to create single pages for nodes in a collection.
8. Configure the template routing
In the gridsome.config.js file, configure the template routing by adding a templates attribute to the file's module.exports:
And between the page <script> tags, add the following method. It will circumvent a webpack issue and allow the site to fetch your products' image URLs:
Wherever you want in the template, add a button with the class snipcart-add-item and the following product attributes. Snipcart will use these to process your product.
As you have done in your product page, query the product data by using the following code:
<static-query>
{
allProduct(sortBy: "id", order: ASC) {
edges {
node {
id
name
images {
small
}
descriptions {
short
}
price
url
}
}
}
}
</static-query>
Note that compared to the product page, the query is slightly different. Long story short, that's because while the Cards component is a standard Vue component, Product is a template component. You’ll need to keep that in mind when invoking your query in our Cards component, which you’ll now do.
Then, just add your Cards component along with some copywriting:
<template>
<Layout>
<div>
<h1>Our ghosts</h1>
<p>
Like your everlasting anxieties, our ghosts are there to keep you
company through the good times and bad times alike.
</p>
<Cards />
</div>
</Layout>
</template>
And voilà!
Our store can now be opened for business. Of course, you could customize it all you want. For instance, I added a homepage and some styling. If you want to check that out, see the demo below.
I enjoyed Gridsome's overall simplicity. For example, its file-based routing and page and template components save a lot of boilerplate code. I also liked that it offers lazy loading and link prefetching out-of-the-box with its g-image and g-link components. Great features to improve application performance!
GraphQL proved to be a bit of a challenge: as a first time user, I had to dig a little to build the right queries to Gridsome's built-in server. However, I can see how it makes importing data to components a breeze once you get the hang of it.
I spent about three days to put this integration together. Those included a lot of tweaking to get the design right.
Besides e-commerce projects, I can see how a blog/media project would be a cool fit for Gridsome, having the right combination of architecture simplicity and static site performance. Maybe for another time!
If you've enjoyed this post, please take a second to share it on Twitter. Got comments, questions? Hit the section below!
About the author
Pierre-Guillaume Laurin Developer
Pierre has been programming for over 5 years now. His go-to languages are Javascript and Python. It doesn’t stop him from getting into other technologies such as Haskell, which he currently is avidly learning. Also a UX enthusiast, he loves to build intuitive products and interfaces that best fit users’ needs.
A Guide to Node.js for E-Commerce [With Koa.js Tutorial]