Shopify with VueJS - Sass - Theme Kit

  • Setup a Shopify custom theme using Vue.js and Sass with more control than Slater.

 

Motivation

Let me begin by stating the reason of this post. You might have noticed that I wrote another blog on why I chose Slater and how I used it to develop themes on Shopify. After digging around the default theme in Slater, it was apparent that the JavaScript they used in the theme was too heavily integrated. They were using PicoApp and I thought to myself, "If I need to learn Pico, why don't I just start a theme from scratch and use my JavaScript framework of choice -- Vue.js?"

If you wish to start a theme from scratch and use Vue.js, read on.

Setting Up Themekit

Follow the installation instructions for Themekit up till you have a password. To get started with a totally barebones theme, I utilised Themekit CLI to create an empty theme that can be uploaded to Shopify. This meant that the most essential folders and files were created by Themekit to make sure it works with Shopify.

theme new --password=[your-password] --store=[your-store.myshopify.com] --name=[theme name]

I've tried other themes such as Skeleton or Starter themes by Shopify (recommended by Slate) but somehow Slate was unable to build them properly, causing issues with the theme when I uploaded them to Shopify. Since I'm gonna be customising my client's site quite a bit, I guess I could start from scratch.

You can also choose to update an existing theme by getting it. Your theme id can be grabbed from the end of the URL, such as when you edit the code from Shopify's site. 123456123456 will be your theme id from this URL https://your-shop.myshopify.com/admin/themes/123456123456.

cd to/your/folder/of/choice
theme get -p=[your-password] -s=[you-store.myshopify.com] -t=[your-theme-id]

Ignore settings_data.json file

In Shopify, settings_data.json file in config is somewhat like a database to store whatever the user has configured in Shopify's theme editor page. Unless you already have populated a settings_data.json, we do not need to push this file if we are starting from scratch. We will just let Shopify's theme editor handle this.

To ignore the file, simply add the following to your config.yml file.

development:
  password: your_password_here
  theme_id: "your_theme_id_here"
  store: your_shopify_store_link_here
  ignore_files:
  - config/settings_data.json

Running Themekit

The purpose of Themekit is to sync your local theme files with Shopify. So whenever you make a change on your machine, Themekit would watch for these changes and push it to Shopify, thereby updating the theme. Unfortunately, there is no live-reloading or local testing built into Themekit. This meant that you have to reload your Shopify site manually after changing a file.

The command to watch for file changes

theme watch

The command to open the theme on Shopify to preview

theme open

Using Gulp for a Sass Workflow

Being a huge fan of Sass, I've always wanted to use it whenever I can. I particularly like the partial imports, nesting of selectors and file structure guidelines to organise my styles. When setting up Themekit, they prompted whether I would be using Sass. If you select it, the CLI will also generate a styles.scss in your assets folder, which will also be referenced in your theme.liquid file.

To make our lives easier, we can use Gulp to compile all the .scss files in the various folders to replace the styles.scss found in assets. I followed the guide by Code Shopify for setting up Gulp.

  1. Install gulp globally npm install --global gulp-cli
  2. Create gulpfile.js in the root of your theme folder
  3. Initialise node npm init
  4. Install dependencies npm install gulp gulp-sass gulp-replace gulp-autoprefixer gulp-rename --save-dev

My gulpfile.js looks like this

var gulp = require("gulp");
var sass = require("gulp-sass");
var replace = require("gulp-replace");
var autoprefixer = require("gulp-autoprefixer");
var rename = require("gulp-rename");

gulp.task("sass", function () {
  //root scss file (import all your partials into here)
  return (
    gulp
      .src("./sass/styles.scss")
      .pipe(sass({ outputStyle: "compressed" }).on("error", sass.logError))
      // add vendor prefixes
      .pipe(autoprefixer())
      // change the file name to be styles.scss.liquid file
      .pipe(rename("styles.scss.liquid"))
      // remove the extra set of quotations used for escaping the liquid string (we'll explain this in a sec)
      .pipe(replace('"{{', "{{"))
      .pipe(replace('}}"', "}}"))
      // save the file to the theme assets directory
      .pipe(gulp.dest("./assets/"))
  );
});

gulp.task("default", function () {
  // this assumes your sass is in a directory named sass
  gulp.watch("./sass/**/*.scss", gulp.series("sass"));
});

As for my sass folder structure, it looks something like this

/sass
  /components
    /_component-a.scss
    /...other components
  /global
    /_typography.scss
  /styles.scss

Run gulp command and it'll run whenever you save a SCSS file. Gulp will update the styles.scss file, which runs some configuration to replace the /assets/styles.scss.liquid file which would then trigger Themekit to sync it with Shopify. As such, we have a pretty good system to manage our .scss files in a nice and organised manner.

Vue.js

Last but not least, Themekit would also ask if you need an application.js file. By choosing so, you will find one in your assets folder. This file will host all of our Vue code.

To install Vue.js, we will make use of the CDN method. Include the following in your theme.liquid file.

<head>
...
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
</head>
<body>
  <div id="app">
    ..
  </div>
</body>
{{ application.js | asset_url | script_tag }}

Then in your application.js file, setup Vue with a custom delimiter since Liquid uses the same delimiter.

const app = new Vue({
  delimiters: ['${', '}'],
  el: '#app',
  data: {
    message: 'Hello Vue!'
  }
})

So from this point onwards, you can make use of Vue in all your pages. If you need to use the data from Vue, you can do so like this.

<span>${message}</span>

Vue.js with Liquid

Some fun thing you can do with Liquid and Vue is to use them together. You can do stuff like this:

<a href="/" v-bind:class="['fr ac sidebar-item item-icon', '{{ handle }}' ? '' : 'active']"></a>

This will check if the handle from Liquid exists and populate the class name.

Dynamic Sections in the Home Page

The power of using a custom theme is giving our clients the flexibility to choose the content for their shopfront. Shopify provides our clients with the ability to add 'sections' we have created for them to add to their home page (index.liquid). Note that only index.liquid will have the ability to add sections as and when the user pleases using the Shopify Theme editor.

To get this working, there are 3 main parts to this.

1. Configuring index.liquid file

To allow for dynamic sections, simply use this line for your entire index.liquid file.

{{ content_for_index }}

2. Adding a custom section

The main gist of a custom, yet dynamic section is to have a "presets" attribute in the schema object. An example of a valid dynamic section is as follows:

<div>
  ...
</div>

{% schema %}
{
  "name": "Blog posts",
  "settings": [
    {
      "type": "text",
      "id": "title",
      "label": "Heading",
      "default": "Journal"
    },
    {
      "type": "blog",
      "id": "blog",
      "label": "Blog posts",
      "info": "Posts will be pulled from this blog."
    }
  ],
  "presets": [
    {
      "category": "Blog",
      "name": "Blog posts",
      "settings": {
        "blog": ""
      }
    }
  ]
}
{% endschema %}

3. Edit settings_data.json file

Go to your Shopify Theme Editor for this theme and check if you are able to "Add section" to your Home Page. If you can see this "Add section" button, skip this step. You're done! Otherwise, read on.

When we configured our theme kit according to the instructions above, I mentioned to ignore the settings_data.json file. Since theme kit has provided us with an empty settings_data.json, we sort of have to trigger Shopify by manually adding our dynamic section. Note that you only have to do this once. Afterwards, your clients can simply add dynamic sections through the Shopify's Theme Editor.

So, for our Blog Posts dynamic section, we will have to add the following to settings_data.json file. I've only gotten this to work the first time I tried it but the idea is there.

{
  "current": {
    ...,
    "sections": {
        "1533544588949": {
          "type": "home-blog-posts",
          "settings": {
            "title": "Journal",
            "blog": "news"
          }
        },
    "content_for_index": [
      "1533544588949"
    ]
  },
  "presets": {
    "Default": {}
  }
}

Current object holds the data user has configured. So, the value of "1533544588949" simply holds the id for our blog post section, as well as the data it comes with.

"content_for_index" stores the section ID added to the index page.

Lastly, the "presets" is used for changing theme which we will be leaving it blank.

With these 3 steps, you should have a dynamic section that could be added to your Home Page on the Shopify Theme Editor.

Things to Note

You have to understand that Liquid variables are populated before Vue is loaded on any page. This means that you cannot programatically refresh the Liquid variable unless you refresh the webpage itself.

I ran into this problem where I have a sidebar cart overlay and I couldn't refresh this cart if I added an item to the cart without refreshing. This means that if the cart shows 2 items, and I add another item to cart, the cart will still show 2 items unless I manually refresh the entire page. To solve this, I simply used the Ajax API to manually load the cart.

Conclusion

I hope this blog post is useful for those who wish to use Vue with the Shopify theme customisation. I'm getting a hang of this and I'll be writing about the project soon.

frontend

Other posts

Setting up a Multi-Themed Application Hero Blog
 

Setting up a Multi-Themed Application • 2022

Uses TailwindCSS and Javascript (React) in this example
Spark Commodities Landing Site Hero Showcase
 

Spark Commodities Landing Site • 2021

Fast, responsive and performant SEO site built with NuxtJS using SSR and TailwindCSS
Nuxt with Animated on Scroll Hero Blog
 

Nuxt with Animated on Scroll • 2020

Animated on Scroll (AOS) is a CSS library to animate elements on websites.
Nuxt with Tailwind CSS and UI Kit Hero Blog
 

Nuxt with Tailwind CSS and UI Kit • 2020

Set up Vue Tailwind UI Kit in Nuxt along with Tailwind CSS, PostCSS and PurgeCSS.
Reassemble Hero Showcase
 

Reassemble • 2020

Reassemble is a UX Design Consultancy based in Singapore. I made for them a consumer facing website based on NuxtJS with Tailwind CSS, Animated on Scroll and Contentful integration.
Temple Cellars Hero Showcase
 

Temple Cellars • 2020

Redesigning an alcohol e-commerce with custom Vue Shopify theme
Slater and Custom Shopify Theme Hero Blog
 

Slater and Custom Shopify Theme • 2020

How I setup Slater, and other tools I considered when researching on the tools to develop a custom Shopify storefront.

Contact