Migrating a Shopify Store to Online Store 2.0 Without Breaking Everything

A practical migration order, the things that silently break, and how to verify you did not lose content along the way.

Share
Migrating a Shopify Store to Online Store 2.0 Without Breaking Everything. Abstract shopify illustration in orange and dark grey on debugly.dev

Disclosure: I spent four years building Shopify themes at Debutify, finishing as CDO. This guide is platform advice rather than product advice, and the method works regardless of which theme you move to.

The short answer

Migrating to Online Store 2.0 means moving from a theme where only the homepage had sections to one where every template does, plus JSON templates, app blocks, and metafields.

The safe order:

  1. Inventory what you have now, especially customisations and app injected code
  2. Set up the new theme as an unpublished duplicate and build in parallel
  3. Migrate content template by template, verifying each
  4. Move hardcoded content to metafields and section settings
  5. Reinstall apps against the new theme rather than copying their code across
  6. Verify with a checklist before publishing, then watch for 48 hours

The single most common failure is treating this as a theme swap rather than a content migration. Your content lives partly in theme code, and that is the part that gets lost.

What actually changes

Sections everywhere. In the old architecture only index.liquid supported sections. Product, collection, blog, and page templates were fixed Liquid files. In 2.0, every template can have sections that merchants rearrange in the editor.

JSON templates. Templates become JSON files describing which sections appear and in what order, rather than Liquid files containing markup. templates/product.json lists sections, and the markup lives in sections/.

App blocks. Apps can register blocks that merchants drop into sections through the editor, instead of injecting script tags. Cleaner, removable, and it means an uninstall actually removes things.

Metafields with proper types and admin UI. Structured content that merchants can edit in admin without a developer, with real types instead of everything being a string.

Theme app extensions. Apps ship their storefront code as an extension rather than editing your theme files.

The practical consequence is that a lot of what used to live in theme code should now live in content, and the migration is mostly about moving it.

Step one: inventory before you touch anything

Skipping this is how migrations lose content.

Export your current theme. Download a zip and put it in version control. This is your reference for everything that follows and the thing you will diff against when something is missing.

shopify theme pull --store yourstore.myshopify.com --path ./theme-backup
cd theme-backup && git init && git add -A && git commit -m "pre-migration baseline"

Find every customisation. Diff your theme against the original vanilla version if you know which theme and version it started as. Every difference is either a customisation you need to carry forward or app injected code you need to handle separately.

diff -r theme-vanilla/ theme-backup/ > customisations.txt

If you do not know the base version, read through theme.liquid, the product template, and any snippet with a name that does not look stock.

List hardcoded content. This is the part people miss. Old themes frequently have content baked into Liquid: shipping information in the product template, a size guide in a snippet, trust badges in the footer, a returns blurb below the add to cart button. None of that is in your database. It exists only in theme code, and if you swap themes it disappears.

Search for text strings:

grep -rn "free shipping\|returns\|size guide\|delivery" --include="*.liquid" .

Every hit is content that needs a home in the new theme, most likely as a metafield or a section setting.

List your apps and how each one injects. For each app, determine whether it uses a theme app extension, an app embed, a script tag, or direct theme edits. The last category is the one that needs work, because that code will not exist in the new theme.

Record your current metrics. Lighthouse scores on your key templates, Server-Timing processing values, and your conversion rate for the previous 30 days. You need a before picture so you can tell whether the migration helped or hurt, and so you have data if something goes wrong after launch.

Step two: build in parallel

Never migrate in place. Add the new theme as an unpublished theme and build it out while the old one keeps serving customers.

Admin, Online Store, Themes, Add theme

Work in the preview. Everything below happens in the unpublished theme.

If you are working with the CLI, shopify theme dev gives you a local development server with hot reload against real store data, which is dramatically better than editing in the browser:

shopify theme dev --store yourstore.myshopify.com

Step three: migrate template by template

Do not do everything at once. Do one template, verify it fully, then move on. When something breaks you want a small surface to search.

Suggested order, easiest to hardest:

Static pages first. About, contact, FAQ. Low risk, and they teach you the new theme's section system.

Blog and article templates. Also low risk, and they surface any content structure issues early.

Collection templates. Now it matters. Check your filtering and sorting still work, and verify that any custom collection layouts carried across.

Product templates. The highest risk and the highest value. This is where most customisation lives and where mistakes cost money.

Homepage last. It looks like the scary one and it is actually the easiest, because it was already section based in the old architecture.

Cart. Verify separately and thoroughly. Cart bugs are the expensive ones.

For each template, work through: does the content match the old version, do all the links work, does it look right at 375px wide, and does the primary action still function.

Step four: move hardcoded content into metafields

This is the genuinely valuable part of the migration and the part that gets rushed.

Say your old product template had this:

<div class="shipping-info">
  <p>Free shipping on orders over 2000. Delivered in 3 to 5 business days.</p>
</div>

Hardcoded in the theme. Every product shows the same text, and changing it requires a developer.

In 2.0, define a metafield:

Settings, Custom data, Products, Add definition
Namespace and key: custom.shipping_note
Type: Rich text

Then in a section:

{%- if product.metafields.custom.shipping_note -%}
  <div class="shipping-info">
    {{ product.metafields.custom.shipping_note | metafield_tag }}
  </div>
{%- endif -%}

Now it is per product, editable in admin, and the merchant owns it.

Use metafield_tag rather than outputting the value directly. It renders the correct markup for the metafield type and handles rich text, file references, and lists properly. Outputting a rich text metafield directly gives you escaped JSON, which is a confusing five minutes the first time it happens.

Good candidates for metafields: size guides, care instructions, ingredient lists, spec tables, shipping notes, badge text, video URLs, downloadable manuals.

Bulk populate with the Matrixify app or the Admin API, because entering metafields by hand for 400 products is not a plan. Export a CSV, fill the column, import it back.

Step five: reinstall apps, do not copy their code

Tempting to copy the app snippets from the old theme into the new one. Do not.

Uninstall and reinstall each app against the new theme, or use the app's own "add to theme" flow. Modern apps register a theme app extension or app embed, which is cleaner than the code they injected into your old theme and will keep working through future theme updates.

Where an app has no 2.0 support, that is a decision point. Check whether the developer has an alternative, or whether a competitor does. Migration is a natural moment to drop apps nobody uses, and most stores have several.

After reinstalling, run the full purchase flow. Add to cart, update quantity, remove, apply a discount, proceed to checkout. Every time.

The things that silently break

These are the ones that do not throw an error and are found by customers rather than by you.

Redirects and URL structure. If any handles change, set up redirects. Shopify has a URL redirect tool under Online Store, Navigation. Losing a product URL that has backlinks and rankings is an expensive, slow to notice mistake.

Structured data. Old themes often had hand written JSON-LD in the product template. If the new theme generates its own, verify you do not have two conflicting blocks, and validate with Google's Rich Results Test. Duplicate or malformed product schema degrades rich results quietly over weeks.

Meta titles and descriptions. If these were built in theme code with custom logic rather than coming from Shopify's SEO fields, that logic needs recreating.

Custom Liquid in settings. Some themes have a custom CSS or custom Liquid field in theme settings. That content lives in settings_data.json and does not always carry across. Check it explicitly.

Translations. If you use Shopify Translate and Adapt or a translation app, verify translated content still resolves. Theme string translations live in the theme's locale files and do not migrate at all, so any custom strings you translated need redoing.

Email templates. Not part of the theme, but people assume notification emails follow the theme's branding. They do not, and a migration is a good moment to check they are not still using colours from two rebrands ago.

Currency and market settings. If you sell internationally, verify pricing displays correctly for each market in the new theme.

The pre publish checklist

Run through this on the unpublished theme before switching.

Product page renders correctly for a simple product, a product with many variants, an out of stock product, and a product on sale. Collection page filtering and sorting work, and pagination works past page one. Cart adds, updates, removes, and applies a discount. Search returns results and the empty state looks right. All navigation menus resolve. Every static page has its content. Mobile layout works at 375px. Structured data validates. Lighthouse on product and collection is at or above your recorded baseline. Server-Timing processing is at or below baseline. Every app functions and the checkout completes end to end with a real test order.

That last one is not optional. Place a real order using a real payment method and refund it.

After publishing

Watch for 48 hours. Check for 404s in your analytics, watch conversion rate hourly for the first day, and read any support tickets carefully because customers find things you did not.

Keep the old theme. Do not delete it. Shopify keeps unpublished themes and reverting is one click. Leave it for at least a month.

Re measure. Compare Lighthouse, processing time, and conversion against your baseline. If conversion dropped, the old theme is right there and you can switch back while you investigate.

Is it worth it

If you are on a vintage theme, yes, and the reasons are practical rather than aesthetic.

Your merchandising team can change page structure without a developer, which is the single biggest operational improvement. Apps integrate through extensions instead of injecting code, so uninstalls are clean. Metafields let you structure content properly. And 2.0 themes are generally faster, since the architecture encourages loading sections only where they are used.

The counterargument is real: it is a project, typically two to six weeks depending on how much customisation exists, and there is risk. Do not start it in Q4. Do not start it the week before a campaign. Do it in a quiet period with time to watch what happens afterwards.