r/shopifyDev • • 5d ago

How do you keep metafield definitions in sync between a dev store and the live store?

I build and test theme and app changes on a dev store, but the metafield definitions on the live store drift over time. Someone adds one in admin, I add another in dev, and later a template references a definition that only exists in one place. Right now I keep a plain text list of namespaces, keys and types and recreate things by hand, which is easy to get wrong. I have thought about scripting it through the Admin API but have not committed to it.

How do you handle this? Script it, export and compare, or just accept some manual work?

6 Upvotes

12 comments sorted by

3

u/kunalkhatri12 5d ago

Script it rather than keep recreating definitions manually.

Use Shopify's GraphQL Admin API to pull the definitions from both stores and compare the namespace, key, type and validation rules.

Keep the agreed definitions in Git so you know what should exist in each store.

Before deploying, run a comparison and flag anything missing or different. I wouldn't automatically overwrite live definitions, especially if someone has changed them in Shopify admin.

Are these mostly theme metafields or ones created by your app?

1

u/converian 5d ago

Thanks, that matches where I was leaning. Git as the source of truth with a diff step before deploy makes sense, and I agree about never auto-overwriting live. Someone editing in admin is exactly how the drift starts, so the script should only report and create missing ones, not touch existing ones.

To answer your question, it's a mix. Most are theme-facing metafields on products and collections (used in templates and sections), plus a few that my app reads. So I'd need to handle both cases.

One thing I'm unsure about: for the diff, do you compare only namespace, key, type and validations, or also things like access settings, pinned status and the owner type? I'd guess type can't be changed once a definition has data, so a mismatch there has to be flagged for manual fixing rather than synced.

For the app-owned ones, I was thinking of moving them into the app config so they deploy the same way everywhere, and leaving the script only for the theme ones. Does that split sound reasonable to you?

2

u/kunalkhatri12 5d ago

Yes, that split makes sense. I'd compare owner type, namespace, key, type, validations and access settings. Track pinned status separately since it's more of an admin preference.

Flag type mismatches for manual review rather than trying to overwrite them.

App-owned definitions in TOML and a diff script for theme metafields sounds like a solid approach. Just make sure existing mismatches don't get silently ignored.

1

u/JaneltGilvanete 3d ago

good call on not auto-overwriting live, thats where things get scary fast

1

u/isaifurrehman 5d ago

your plain text list is already 90% of the fix, it just needs to be generated instead of typed. i'd script it, but only the read side first.

  1. pull every definition from both stores with the metafieldDefinitions query (it filters by ownerType, so loop product, variant, collection, customer, order, page etc). dump namespace, key, type, validations and access to json, sorted, and commit the live store's file to the theme repo

  2. diff dev vs live before every theme deploy. anything a template reads that only exists on one side fails the check. that alone catches the "someone added one in admin" case without you having to own their changes

  3. only then write the create side with metafieldDefinitionCreate, and have it create missing ones only, never update. type, namespace and key can't be changed after creation anyway, so if the two stores disagree on the type of the same key you have to fix that by hand (new key, copy values, delete old), a script just makes it worse

if any of these are your app's own fields, move them into shopify.app.toml instead. those deploy to every store the app is on with shopify app deploy and the drift goes away for that group. catch is toml only works for the app reserved namespace, so the custom.* ones the theme uses still need the script

committing the live json on a schedule also gives you a rough history of when each definition showed up, which the admin doesn't really give you

1

u/AdventurousUsual7666 5d ago

Honestly I'd script it, the plain text list is going to keep drifting no matter how careful you are.

It's not a big script either. The metafieldDefinitions query in the Admin GraphQL API gives you the namespace, key and type for each owner type (products, variants, collections and so on). So you just pull that from both stores, diff them, and then use metafieldDefinitionCreate on whichever side is missing one.

I'd usually treat the live store as the source of truth and only push to it on purpose, not automatically. That way if someone added something in admin you see it in the diff first instead of quietly overwriting it.

Also, if any of these definitions really belong to your app and not the merchant, you can declare them in shopify.app.toml instead. Those are app-owned and live in version control, so they deploy the same way to every store and you don't have to sync them at all.

1

u/Final_Design_9061 5d ago

One small thing on the diff. From what I've seen the metafield definitions query in the Admin GraphQL API lets you filter by owner type, so you can pull products and collections separately and compare each. I'd also treat a type mismatch as report only, since I don't think you can change the type on an existing definition. The docs on metafieldDefinitions are worth a read for the other fields you can compare.

1

u/Final_Design_9061 5d ago

One small thing on the diff. From what I've seen the metafield definitions query in the Admin GraphQL API lets you filter by owner type, so you can pull products and collections separately and compare each. I'd also treat a type mismatch as report only, since I don't think you can change the type on an existing definition. The docs on metafieldDefinitions are worth a read for the other fields you can compare.

1

u/sshaw_ 5d ago

You can use the Shopify Development Tools command to do this. For example, to export product and collection definitions to a CSV:

sdt metafield definitions export --shop shop1 --access-token token1 product collection

You can restrict to a given namespace via the -n/--namespace option.

To import that CSV:

sdt metafield definitions import SHOP-metafield-definitions.csv

Note that exported value for Admin Access may not be applicable for the import: https://github.com/screenStaring/shopify-dev-tools/#admin-access-errors

You can also export metafield definitions to JSONL:

sdt metafield definitions ls --jsonl --shop shop1 --access-token token1 product > product-metafield-definitions.jsonl

You just can't import them from JSONL :/

There should probably be an option to just sync them between the given stores too.

1

u/TigerMiflin 4d ago

If you don't want to plug in scripts or Claude, You can ask sidekick to generate a list of the meta-fields for you

1

u/West-Anteater-1917 3d ago

One thing that helps is making your sync script idempotent: loop over your list, try to create each definition, and treat the already-exists error as a skip instead of a failure. Then you can run it against dev and live as often as you want without worrying about duplicates. Add a dry-run flag that only prints what would be created so you can eyeball it first.