Building a Vue.js SPA to Sell Developer Tees

In a rush? Skip to Vuejs SPA tutorial

Stereotypes can be a funny thing.

Some are nice like Swedes are gorgeous; some are mean like Americans are fat and Italians are “passionate;” and some seem downright true like all Canadians are polite.

But if you travel enough, you know these are typically gross over-generalizations and, usually, are more divisive than anything else.

And that’s why I love coding so much. It’s way more open-minded. When I meet someone writing in PHP, they’re more than happy to listen about my Vue.js SPA project, for example. And I’m more than happy to listen to what they’re working on, so long as it isn’t a WordPress site (just kidding).

But, hopefully, you get my point. It’s this international inclusiveness among developers that inspired a friend and me to start Maison Futari.

In this post, I am going to:

  • Tell you what inspired Maison Futari
  • Discuss why I chose Vue.js to create it
  • Give a step-by-step Vue.js SPA tutorial
  • Share my experiences (good and bad) with using Snipcart as my shopping cart

Let's get started!

Inspiration for my Vue.js SPA project

First, a little bit of history. I’ve been big into coding since I was 16 years old which means my programming anniversary just hit double digits (oh, how time flies). My love of coding dances between passion and obsession, depending on my mood. So sometimes, when I see someone playing with a few lines of code, I love to dive into meaningful conversations with them.

Again, that’s just the charm and power of programming: it connects people.

Fast forward to Maison Futari, my online T-shirt store that lets people know your passion for programming matches their own.

Choosing Maison Futari’s Tech Stack

Maison Futari Vuejs SPA.png

Ok, so we had the shirt design. The next step was obviously getting the product online which begged the question: how do I want to build this site?

In the past, I’ve worked as a backend developer, but not too long ago I shifted gears. I’m all frontend now! And I needed something that would allow me to stay on the frontend while keeping my site both sleek and interactive.

So I looked over my options. First up was using JAMstack, though I had some initial hesitations.

For those who are new to JAMstack, it’s essentially a paradigm that, in the most basic terms, shifts web development away from the backend and allows developers to build dynamic, client side sites. Using JavaScript, APIs, and Markup (hence the “JAM”), frontend devs can avoid some of the pitfalls of working with a typical CMS.

JAMstack is great but comes with its pros and cons like any new model or technology. Overall, I think that JAMstack is definitely going to be the future of simple websites with minimal content, if it isn’t already.

But that doesn’t mean there aren’t disadvantages to this holy grail. The biggest flaw for me is the fact that the compiling data gets slower and slower after a certain amount of content. I know Gatsby is planning on fixing this problem, but they just aren’t there yet. Also, I’m aware that there are some exceptions like MailChimp and Redbull. But globally speaking, if you have a site with millions of pages, JAMstack just isn’t as viable—yet.

But there was definitely option #2: going all retro-JAMstack by using a SPA.

What is a SPA?

A single-page application (SPA) is a dynamic web page which enhances UX by rewriting your current page rather than going to the server to reload new pages. In other words, SPAs allow you to stick to the frontend because the application runs entirely through your browser. The benefit is that there’s less back and forth between the front and backend.

Less back and forth = faster page loads = better UX

Even if you don’t know it, you’re probably already familiar with single-page applications as they’ve been around for a long time. Gmail was the first to really become popular. And by the late 2000s, SPAs were definitely a well-established concept for devs; but as static sites became more and more popular, programmers decided to give a name to the decade-long trend that encompassed both. Hence, we now put SPA’s under the wider JAMstack umbrella.

Just try not to confuse the two. SPAs are browser-based applications and JAMstack is a frontend paradigm. They’re related but different.

And like everything, there’s always a downside.

It can be hard to mix a basic SPA with other popular frameworks in the JAMstack, like Nuxt.js for example. Hard, but not impossible. Parts of your site can be statically generated, and other parts can be left dynamic in a classic SPA manner.

So, for my purposes, I wanted to have static pages and login pages, but I didn’t want my login pages generated. The only solution for something like this today is server-side rendering (SSR). And while I was tempted to use a CMS with a framework like Next, I really just wanted to make the frontend without even worrying about backend templating.

The good news is that my site wasn’t going to have millions upon millions of pages or even really complex features. So I decided my best option for building a website while sticking strictly in my wheelhouse, the frontend, would be a SPA with an e-commerce integration (i.e. Snipcart).

Now I had my gameplan but needed the framework. After a bit of playing around, I settled on Vue.js.

Building the Vue.js SPA


I graduated from University in 2013 which is when you could say I started coding professionally. That said, I didn’t get into Vue.js until late 2014 because the framework took a while to gain popularity in France after its release earlier that year. I had actually been working with AngularJS but found, for me, there were just way too many performance issues. If you’re an Angular fan, it’s nothing personal! It just wasn’t working out for me. So I searched for alternatives.

With time, Vue.js became the solution I was looking for.

Truth be told, I was learning Vue at the same time as React and, to make a long story short, all the Vue.js features won me over. The biggest difference was in the templating. With Vue, I was able to use regular HTML which was more complicated with React. Plus, Vue has really great tooling.

Now with everything in place, it was time to build my Vue.js SPA. Here’s how I did it:

My preferred way to install Vue is with the GUI provided by Vue CLI. You can install Vue CLI via yarn or npm

npm install @vue/cli -g

yarn global add @vue/cli

Then, you can open Vue GUI with this command: vue ui

Follow the steps to create your new project, in my case, I chose:

  • Babel
  • Router
  • Vuex
  • CSS Pre-processors : SASS/SCSS
  • Linter
  • Unit Testing

Whenever I create a new project, I like to add these two folders:

  • config: directory where I put some constants and configure some plugins.
  • services: directory where I put non-Vue-related classes or functions (e.g API classes, utility functions…).

I also used two very useful Vue libraries, the first one is vue-meta that you can find here on Github. This plugin makes it very simple to add some very important metas and titles to your site. This will help for SEO.

I also used vue-i18n to deal with multi-languages. This is a very well done library. You can see it here.

Then, I also like to use SCSS. I usually create a scss folder inside the assets folder. This is where I’ll add all my global SCSS files. In this specific project, I created a snipcart.scss stylesheet to override Snipcart’s default CSS file.

To load all my global SCSS variables and mixins into each component, I created a custom vue.config.js file to customize the Webpack config for this project.

// In the vue.config.file
// I load globally in all my components 2 files
// that DO NOT contain CSS but just variables and functions
// If you add CSS in those files they would be duplicated in each component
module.exports = {
  css: {
    loaderOptions: {
      sass: {
        data: `
          @import "@/assets/scss/variables.scss";
          @import "@/assets/scss/mixins.scss";

Lastly, you may have noticed that I included Vuex in my project, why? To handle some communication between components, in my case : currency handling between the currency select and the product cards. And voila! C’est fait! Apart from that, I tracked my site using Google Analytics and deployed my SPA on firebase hosting. Otherwise, you now have everything you need to build a replica of my Vue.js SPA example.

Adding a cart to my Vue.js SPA Template


Before choosing Snipcart, I looked at all the solutions that would allow me to work exclusively on the frontend. I didn’t want to have some generic shopping cart. After all, if I had wanted some out-of-the-box solution, I could have just gone with a drag and drop hosting site. But I like having control over my page and its look.


Snipcart was definitely the most adaptable to my situation. But like I mentioned about JAMstack, there’s always good and bad. Let’s start with the latter.

Yes, the cart theme’s CSS was easily overridable and, in the end, I was able to completely change the look of my cart. However, I definitely had to do some digging to figure out how. Also, sometimes Snipcart didn’t merge similar products which makes it weird for the users in some scenarios.

Then I had to hard code the product definitions in my index.html page because the .json file didn’t seem to verify if the product existed or not. That said, I’ve since been told that this is something the Snipcart team could have helped with (but I’m a hands-on, figure-it-out kind of coder anyways).

Finally, some features were lacking such as specifying more than one country for custom shipping and discounting products in multiple currencies.

In the end, these weren’t deal breakers for me as I was able to find workarounds. Which means that Snipcart ended up being the shopping cart solution most suited to my needs. And that brings us to the good.


With Snipcart, I only needed to include two scripts. Though I honestly wasn’t thrilled that one of those scripts was jQuery, I decided it was worth the compromise. Plus, Snipcart’s dashboard allowed me to easily manage my orders and create discounts.

The cool part is that Snipcart’s data attributes were really fast to integrate because Vue uses templates. The tricky part, though, was simply helping Snipcart find the products in my page but once that was done, all I had to do was style my cart. And, again, overriding the CSS was fairly easy.


Editor’s note: We 100% agree with Ariel’s description of Snipcart’s drawbacks. We are excited to say that the v3.0 release (in just over a month) will address many of these issues. We will have much fuller/detailed documentation on how to completely change the look of your cart. Also, v3.0 will be completely doing away with jQuery!

Closing thoughts

I enjoyed building my Vue.js SPA and am happy with the Snipcart integration. It gave me the freedom to customize my cart and I never had to play around with the backend. I think my next move will be using Snipcart hooks to connect Snipcart with my suppliers. Also, if I had more time, I would have used Snipcart’s SASS variable to generate the CSS (which would have made it more maintainable).

This is my 6th time working with Vue and I would say that all the Vue.js features make it adaptable for almost any project, whether it’s an SPA or not. For example, it could be used to create small widgets in a server-rendered website (a widget like a chat box, for example); it could be used to create an online player with a YouTube API; or it could be used to create some docs with the help of Vuepress like the docs of directus.

Again, all really great possibilities and while my project ended up being a Vue.js SPA for my e-commerce store, I would be excited to play around with more possibilities in the future!

Editor’s note: We want to thank Ariel for his contribution to our blog! For readers interested in learning Vue / JAMstack e-commerce, you can check out the following links:


JAMstack E-Commerce:

If you've enjoyed this post, please take a second to share it on Twitter. Got comments, questions? Hit the section below!

Suggested posts: