How to manage multiple Shopify themes with a single GitHub repo

John

Written by John

2022
ShareShare on XShare on FacebookShare with Email

Unless you want the hassle of updating assets across multiple Shopify themes manually – not to mention all the issues that come along with it (and, believe me, you don’t) – then you’ll need a single repo for all stores.

But Shopify multi-stores and GitHub don't exactly play nicely together out of the box. Now that we’ve got the CLI and GH integration, it's a lot better. Not perfect, but with a little bit of dev work, it can turn out fine – for the most part.

Here’s how we’ve made managing multiple Shopify stores a whole lot easier. All it takes is a simple setup and a couple of changes to the theme management process.

What's the problem?

The problem with the GitHub integration on Shopify is that things change on both sides. Apps inject things, assets are added, the list goes on. But the prime conflict culprits are JSON templates.

JSON templates are basically a flat file structure approach to the CMS. Every change you make to a JSON template is saved to the store files rather than a database. This is normally fine, and pretty handy most of the time because you know that any changes your client makes to the store customiser are automatically backed up to GitHub. Plus, it's super easy to then get those changes locally just by pulling the theme branch.

Where it gets tricky, however, is multi-stores running off the same theme. For instance, when both of those stores use the same file to load their contact page address, but they need to have different text, that's conflict territory. Not where we want to be.

So this is where things begin to get tricky. We want both stores to save their data to the repo, so everything is backed up, yet we want them all to run from the same theme so that when we add new features, it's sent to all sites and we don't have to copy code from one theme to the next. I've worked on sites with a repo per store, it's not fun!

What can we do?

Well, there's a solution that we're using at Series Eight and it's working pretty well for us so far. It's quite simple to do, too – just a little bit of setup on GitHub and some common practices when adding new features or working with Shopify themes.

First, you'll need to consider how your repo is structured. What we've found works best is working with a main branch, and then when new stores are needed, we create independent branches for those stores. For example:

Each of those branches is the live store theme connected via a GitHub integration. Now, clients can edit those stores' customisers individually and everything is backed-up. Problem one solved.

Now, imagine we're working on a new feature. We start by branching off the main branch. We'll do our thing then PR or merge our feature branch into the main branch, so that main is always in line with the latest codebase. From there, we can merge the main branch into each of those store-specific branches and our new feature is now on each of those branches too. Problem two solved - well, almost.

There are some small issues still, and doing this with one or two sites is fine. But what happens when there are five? Or 13? (Yeah, that's been a thing). That's a lot of merging...

Slight issue #1: Apps.

Apps inject things. Random things. Lots of random things sometimes. Those apps are sometimes specific to one store, or use unique IDs. I'm not sure if there's anything clever you can do about this. With some apps/IDs, you can offload to CMS fields in the customiser (Header Scripts, Footer Scripts, GA ID, App Section embeds, etc.). Other times, a simple conditional will have to suffice.

Slight issue #2: Working with store-specific JSON templates.

Pretty rare, and super slight, but if you're trying to debug an issue with content-specific to one of those stores' JSON templates, you're not going to have access to that content on the main branch. You could branch off the store branch, but if you end up changing template code, you're going to want to merge back into the main branch to fix it on the other stores, too. There are probably a few ways to deal with this. The simplest way I've found is to just copy-paste the contents of the JSON file from the production theme file editor into the Shopify Development Theme file editor. This way, your "local" development environment can match any of the store's content and you don't have to worry about accidentally adding something on the main branch because it isn't part of your codebase/PR.

Slight issue #3: Merging all those branches.

It depends on how many stores you're running, but this can get old real fast. There's a pretty simple solution for you though, and it comes in the form of GitHub Workflows. The one below, for example, will take any push/PR to the main branch and auto-merge the main branch into the specified store branches. It purposely won't merge any changes to JSON files, you'll have to do that manually as we don't want to risk accidentally overwriting content. But otherwise, it should save you a job. All you’ll need to do to use the workflow is change the appropriate branch names and add them to your `.github/workflows/` folder.

name: Merge to store themes
 
on:
 push:
   branches:
     - main
   paths-ignore:
     - 'templates/*.json'
     - 'config/*.json'
     - 'locales/*.json'
 pull_request:
   branches:
     - main
   paths-ignore:
     - 'templates/*.json'
     - 'config/*.json'
     - 'locales/*.json'
 
jobs:
 build:
   runs-on: ubuntu-latest

 steps:
     - name: checkout
       uses: actions/checkout@v2
     - name: merge
       uses: mtanzi/action-automerge@v1
       id: merge-UK
       with:
         github_token: ${{ github.token }}
         source: 'main'
         target: 'live/UK'
     - name: merge
       uses: mtanzi/action-automerge@v1
       id: merge-EU
       with:
         github_token: ${{ github.token }}
         source: 'main'
         target: 'live/EU'
     - name: merge
       uses: mtanzi/action-automerge@v1
       id: merge-AUS
       with:
         github_token: ${{ github.token }}
         source: 'main'
         target: 'live/AUS'

Slight issue #4: Clients changing the published theme.

Some clients like to adjust their theme privately, on an unpublished theme, either to test things out or to get the store ready for a new product launch or sale. This is kind of a problem with the GH integration, as duplicating the store and publishing a duplicate theme will break the GH connection. We don't want that.

An easy way to prevent this is to make sure the client is aware of the GH integration, and let them know to duplicate the store first, then publish the duplicated store, whilst making changes to the now drafted GH connected store. Then, when it's ready to publish, it'll keep the GH connection. This doesn't help when changes are being made on both the live and the draft theme at the same time but 🤷.

Problem solved

With the above multi-store GitHub workflow, things have been going pretty smooth. As long as the process is there, there's rarely room for issues to arise. And when they do, they're caught and manually adjusted before they hit production. Job done.


Let us take you further than you’ve ever been
SERIES EIGHT © 2024