Problem / Solution 8 min read

How to Stop Overwriting Your Client’s Theme Editor Changes

A client spends an afternoon configuring sections. You push a CSS fix. Their work is gone, and you did it. Here is why it happens and the flag that prevents it.

TS
ThemeSync Team
ANATOMY OF AN ACCIDENTAL OVERWRITEClient reorders sectionsand writes copy in thetheme editor.2:00pmYou fix a CSS buglocally. Unrelated file.4:30pmYou run theme push. Ituploads yoursettings_data.json too.4:31pmTheir afternoon isreplaced. No error, nowarning.4:31pm"Did you undo everythingI did yesterday?"9:00amNothing errored. Nothing warned. The work is simply gone.

Why a CSS fix can delete an afternoon of work

Shopify themes keep two very different kinds of state in the same folder, and the theme editor writes to one of them.

  • Code — Liquid, CSS, JS. You edit these in your editor.
  • Configuration — config/settings_data.json and the JSON files in templates/. These hold which sections exist, in what order, with what settings and copy. The theme editor writes here.

When a client drags a section, changes a heading, or swaps an image in the customiser, none of that is stored in a database somewhere separate. It's written into JSON files on the theme.

shopify theme push uploads your local files over the theme's files. It isn't a merge and it isn't aware that someone else has been working. Your settings_data.json — which reflects the state whenever you last pulled — replaces theirs. The push succeeds. Nothing warns you.

The reason this hurts more than a normal bug: the client did the work, and you destroyed it. There's no artifact to point at, no error message, and no way to recover it unless something happened to pull those files first. From their side it looks like carelessness with their time.

The reverse direction breaks too

The same gap runs the other way. A client reorders sections while you're building. You pull later, and their JSON overwrites the section config you were setting up in code. Both directions lose work, because both are last-write-wins on the same files.

The flag that closes the gap

The Shopify CLI has a mode for this. Running the dev server with --theme-editor-sync makes changes made in the theme editor flow back down into your local files while the session is running:

Dev server that watches the theme editor too
shopify theme dev \
  --store client-store.myshopify.com \
  --theme 123456789 \
  --theme-editor-sync

With that running, a client changing section settings in the customiser results in your local settings_data.json and JSON templates being updated. Their work lands in your working copy, where it can be committed, and your next push carries it forward instead of replacing it.

PUSHING WITH AND WITHOUT EDITOR SYNCWITHOUT EDITOR SYNClast write wins✗Push replaces client section config silently✗No warning, no conflict, exit code 0✗Client work exists only on the theme, then not at all✗Nothing in git records what was lost⚠Discovered by the client, not by youWITH --theme-editor-synctwo-way✓Editor changes flow down into local files✓Client config can be committed to git✓Your next push carries their work forward✓Section changes show up in a diff⚠Only while the session is actually running
The catch worth knowing: it only syncs while the session runs. If the dev server is down for two days and the client spends those two days in the customiser, you're back to the original problem. This is one of the reasons a session that stays up matters more than it sounds.

The JSON churn problem, and how to live with it

Two-way sync introduces its own annoyance: settings_data.json becomes a busy file. Every colour tweak and section reorder is a diff, often a large and unreadable one. Teams react by ignoring the file, which recreates the original problem.

What works better:

PracticeWhy
Commit config changes separately from code changesKeeps code review readable and makes a config regression easy to revert on its own
Use a commit message convention like config:You can find "when did the homepage sections change" in seconds
Never resolve a settings_data.json conflict by handTake one side wholesale. Hand-merging this file produces themes that fail to render sections
Agree who owns config during a phase"You're in the customiser this week, I'm not pushing config" removes the collision entirely
Pull before you push, every timeThe cheapest habit on this list and it catches most of it
Pull-before-push, as a habit
# See what changed on the theme before you overwrite anything
shopify theme pull --theme 123456789 --store client.myshopify.com
git diff --stat

# Config-only changes? Commit them on their own.
git add config/settings_data.json templates/
git commit -m "config: client section changes from theme editor"

The conversation that prevents most of this

Most overwrite incidents are a coordination failure wearing a technical costume. The client had no idea that "moving a section" and "your code" touch the same files, because there's no reason they would.

Setting expectations once, in plain language, at kickoff:

"While we're building, the theme editor and our code both write to the same configuration files. If you'd like to arrange sections or edit copy yourself, tell me before you start and I'll make sure it flows into our files rather than getting replaced on the next deploy. If you'd rather not think about it, send me the changes and I'll make them."

That paragraph does two useful things. It gives the client a safe way to participate, and it makes any future incident a shared process gap rather than your mistake.

Give them somewhere better to put feedback

A lot of client customiser editing isn't really editing — it's the only way they can show you what they mean. If the alternative is a paragraph in an email, dragging the section themselves is genuinely easier for them.

Give them a way to point at the thing on the page and say "this should be above that" and most of the risky editing stops, because the editor was never what they wanted. They wanted to be understood.

How ThemeSync handles editor changes

  • Themes pushed for review run with editor sync enabled. When a theme is pushed to the store for a client to work with, the follow-on dev session runs with --theme-editor-sync, so customiser changes come back into the tracked files rather than stranding on the theme.
  • The session stays up. Because the dev server runs in the cloud rather than on a laptop, the sync window isn't limited to when your machine is awake — which is when clients tend to be in the customiser.
  • Everything lands in a git branch. Config changes are commits. "When did the homepage sections change, and to what" has an answer, and a bad config change can be reverted on its own.
  • You can see uncommitted theme changes before pushing. A diff of what's changed on the theme versus what you're about to upload turns silent overwrites into a decision you make deliberately.
  • Clients get pinned comments as the default. Pointing at an element and typing a sentence is easier than the customiser, so there's less reason for them to be in there rearranging things at all.

Takeaways

  • Theme editor changes live in config/settings_data.json and the JSON files under templates/ — real files on the theme, not separate storage.
  • theme push overwrites rather than merges. It will replace client configuration and report success.
  • shopify theme dev --theme-editor-sync pulls editor changes back into your files, but only while the session is running.
  • Pull before every push. It's the cheapest habit that catches most of these.
  • Never hand-merge a settings_data.json conflict — take one side whole.
  • Tell clients at kickoff that the customiser and your code share files, and give them a better way to give feedback than doing it themselves.

Never overwrite a client’s work again

ThemeSync keeps editor sync running on review themes, commits config changes to git, and shows you a diff before anything gets pushed over the top.

Try ThemeSync Free →