The Shopify GitHub integration in practice
The Shopify GitHub integration in practice at XXLplant: how the connection works, what is not in git, working with the Shopify CLI, and five pitfalls in JSON templates and translations.

Most people customise a Shopify theme in the Shopify theme editor. That is quick, but afterwards you cannot see what changed, who changed it or why. At XXLplant, ZAZU's own online shop, we therefore work with a theme connected to GitHub. Between 8 June and 27 September 2026, that connection recorded 279 changes.
This article is for developers who maintain a Shopify store with several people, or who let AI agents work on a theme. It covers how the connection works, what does and does not end up in the repository, how we work from the command line, and which pitfalls we ran into.
How the Shopify GitHub integration works
Shopify connects a theme to one branch in a GitHub repository. From then on, the two keep each other in sync in both directions. A push to the branch shows up in the theme. A change in the Shopify theme editor comes back to the branch as a commit, with shopify[bot] as the author.
At XXLplant, the ratio between the two says a lot. Of the 279 commits, 277 came from shopify[bot] and 2 from a person. That is because we mostly work on the theme from the command line, and Shopify records every change that comes in that way as a commit as well. The repository is therefore the complete history of the theme, wherever the change came from.
What is and is not in your GitHub repository
This is in it: the Liquid templates and sections, the snippets, the assets, the JSON templates with the settings for each page, config/settings_data.json with the theme settings, and the language files in locales/. Everything you set on a section in the editor ends up in a JSON file, and so in git as well.
This is not in it, and it surprises almost everyone:
- Translations of the theme content. If you translate a section heading through the translation app or through
translationsRegister, Shopify stores that translation outside the theme files. Only the language files inlocales/are in git. - Metafields and metaobjects. The text of a species page or the questions in an FAQ block live in the store's database.
- Menus, products, collections and the settings of markets.
For a store in nine languages, that means the repository keeps the structure and the store keeps the content. If you roll a theme back to an old commit, the translations do not roll back with it. At XXLplant, we registered roughly two thousand translations of theme content on 5 October. Those live in Shopify. If you want to be able to restore them, keep the scripts and exports you wrote them with as well, because git will not do that for you.
How to work on your theme with the Shopify CLI and the API
For individual files we use the Shopify CLI: shopify theme pull and shopify theme push with --only to move a single file. On the live theme, the CLI asks for --allow-live, so you do not overwrite the wrong environment by accident.
For automated work, such as an agent changing twenty templates at once, we use the Admin GraphQL API through shopify store execute. The themeFilesUpsert mutation writes one or more files in one go, and the theme(id) { files } query reads them back. The advantage is that you pass the file content as a variable and get the output back as JSON, so a script can check what was actually saved.
That check is necessary. Shopify validates a JSON template against the section schema and throws away any setting the schema does not recognise. Your push looks successful, but the setting is gone. Read the file back after every push and compare it.
Pitfalls of keeping a Shopify theme in GitHub
These are the things that cost us time, with what we do about them now.
A glob in --only can delete files
shopify theme push --only "locales/*.json" also matches the schema files, such as locales/en.default.schema.json. If such a file exists in the theme but not locally, the CLI deletes it. The theme editor then shows "missing translation" everywhere. So before you push with a glob, make sure every file the glob can match is present locally.
A default value in a schema cannot be translated
A section with "default": "Waarom je planten koopt bij XXLplant" in its schema shows that text as long as nobody fills in the setting. Shopify does not offer such a default value for translation, so the German page shows Dutch. The fix is to put the text in the JSON template as a real setting. It then appears as a translatable field. At XXLplant we did that for four sections on 5 October.
The editor and the code write to the same files
Settings from the editor are stored in the same JSON files a developer works in. If someone changes a piece of text in the editor while you are editing the same template locally, your push overwrites their change. So always pull the latest version just before you push, and push file by file instead of the whole theme.
The page cache hides your change
Shopify serves bare collection and product URLs from its own page cache, even when the CDN header says otherwise. Your change is live, but the page shows the old version for a few minutes. Check a push with an extra parameter in the URL that bypasses the cache, such as ?sort_by=title-descending.
A new theme has no connection
The connection belongs to one theme. If you build a new version as a copy and publish it, the live theme is no longer connected and the history in GitHub stops following it. Connect a new version to its own branch before you publish it, and merge that branch into your main branch afterwards.
How to organise branches and themes
The workflow we recommend now has three layers. The main branch is connected to the live theme. Every larger change gets its own branch, connected to its own unpublished theme with its own preview link. That is where you test and where someone else reviews it, and only then does the change go to the main branch through a pull request.
That gives you three things. With every mistake, you can see which lines changed and roll them back with a single revert. Several people and agents can work at the same time without overwriting each other's work. And you can show a client a new page while visitors still see the old one. XXLplant's translations in nine languages, the 3D viewer and the plant doctor were all put into the theme through the command line and the API. What those parts do is in Shopify SEO and 3D models with AR in practice.
Who the GitHub integration is worth it for
For a small store that rarely changes its theme, the Shopify editor is enough. If several people work on your online shop, you sell in several languages, or you change the theme every week, the connection pays for itself the first time you roll back a mistake in a minute. How XXLplant sells in thirteen countries is in Shopify Markets: one shop in thirteen countries.
Want to connect your Shopify theme to GitHub without the editor breaking? Then we'll set it up together.
What this means for your business.
Answer three questions and you will know where it makes most sense to start.
How we build online shops