Deploy a Shopify theme to multiple stores from a single repository

23 March 2026

The problem

Sometimes we want the same theme code deployed to multiple stores. For example, you might have a live store and a staging store, or you might have multiple live stores for different regions that all use the same theme code but have different content.

This is not possible using the native Shopify GitHub integration. This is because the native integration only allows you to connect one store to a GitHub repository.

Even if you could connect multiple stores, changing the content on one store would push that change back to the repository and then that change would be deployed to all the other stores, in most cases this is not desirable as it doesn’t allow you to have different content on each store.

The solution

Instead of using the native Shopify GitHub integration, we can use the Shopify CLI in a CI/CD pipeline (in this case, GitHub Actions) to deploy to multiple stores. This allows us to deploy the same theme code to multiple stores without overwriting the content on each store.

Setup

This guide is for theme code hosted on GitHub.

The first step, if it’s in use, is to disconnect the store from the GitHub repository in the Shopify admin.

Next you will need to install the Shopify Theme Access app on each store and generate a password for each store. This effectively gives you an API key with permissions to theme_read and theme_write.

Save these passwords in GitHub secrets, for example you could name them STORE_1_PASSWORD, STORE_2_PASSWORD, etc.

Once you have your secrets set up, you can set up a GitHub Actions workflow to deploy to multiple stores. Create a new yaml file in your repository’s .github/workflows directory. e.g. .github/workflows/deploy-theme.yml

You can use the following workflow as a starting point:

name: Deploy theme
on: 
  workflow_dispatch:
  push:
    branches: [ main ]
env:
  FLAGS: --ignore config/settings_data.json --ignore templates/*.json --ignore locales/* --ignore sections/*.json
jobs:
  deploy:
    name: Deploy $
    runs-on: ubuntu-latest
    strategy:
      matrix:
        include:
          - name: "Store 1"
            theme_id: 000000000000
            store: store1
            secret: STORE_1_PASSWORD
            use_flags: true
          - name: "Store 2"
            theme_id: 000000000000
            store: store2
            secret: STORE_2_PASSWORD
            use_flags: true
    steps:
      - name: Checkout repository
        uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 24
      - name: Install Shopify CLI
        run: npm install -g @shopify/cli
      - name: Deploy theme
        run: |
          shopify theme push \
            --allow-live \
            --nodelete \
            --theme $ \
            --store $ \
            $ \
            --password $

This flow is triggered either on a push to the main branch or manually through the GitHub Actions interface. It will deploy the theme to each store defined in the matrix, using the corresponding password from the secrets.

For each store, you must make sure the configuration in the matrix is correct:

Once this file is set up and pushed to the repository, the workflow will run and deploy the theme to each store. You can check the progress and results of the workflow in the GitHub Actions tab of your repository.

Further explanation

The FLAGS environment variable is used to specify which files to ignore during deployment. In this example, we are ignoring config/settings_data.json, all JSON templates, all JSON locales, and all JSON sections. This allows us to deploy the same theme code to multiple stores without overwriting the content on each store, as these files often contain store-specific content. At the time of writing, these are the only files that are written to from changes made in the Shopify admin.

Within the store matrix, use_flags is a boolean value that determines whether to use the FLAGS environment variable. This is useful if you want to deploy to some stores with the flags and some without. For example, you might want to deploy to a staging store without the flags so that you can test changes to content before deploying those changes to the live store with the flags enabled.