Shopify
How to migrate a Dawn store to Shopify Horizon
A Shopify Horizon theme migration is not a theme switch. If you treat Dawn as a skin you can peel off and drop Horizon on, you will break apps, custom sections and the Core Web Vitals you already paid to fix. I am Alan Vo, a Gold Coast web developer. I have spent 18 years shipping storefronts, including Shopify Plus jewellery and fashion work. Horizon is Shopify's current reference architecture. Dawn is still a valid store. The move is a rebuild with a production checklist, not a setting.
Shopify's own Horizon theme listing and the theme architecture docs are the source of truth for what the platform now expects. This note is how I actually run the job on a live catalogue.
Why a Shopify Horizon theme migration is a rebuild
A Shopify Horizon theme migration is a rebuild because Dawn and Horizon do not share a block model. Dawn is Online Store 2.0 with sections that own a flat list of blocks. Horizon is still Liquid and JSON templates, but the unit of layout is a reusable theme block that can nest. Shopify did not ship a converter. Settings, custom Liquid and section schema do not map one-to-one.
That is the part marketing decks skip. Horizon is not "Dawn with a new homepage." Header and footer become block-driven groups. Product cards become trees of nested blocks. Interactive pieces such as the variant picker, gallery and cart drawer often ship as web components. Apps that listened for native form events on Dawn can go silent inside a shadow tree.
I treat Horizon as the default for a new build in 2026. I stay on Dawn when the live store is converting, the custom Liquid is still maintainable, and the field Core Web Vitals are already in the good range. Rebuilding a converting Dawn store "because Horizon is the new default" is how you donate a quarter of revenue to a layout shift.
The trigger that does justify the work is a Dawn codebase that has become expensive to change: duplicated sections, apps injected through snippets, merchandisers who cannot edit without a developer, or a brand refresh that would need a new homepage anyway. If you are already rebuilding, rebuild on Horizon. If you are not, leave Dawn alone and spend the hours on catalogue SEO and checkout.
What actually changed between Dawn and Horizon
The architecture change is theme blocks plus content_for, not a new colour palette. In Dawn you defined blocks inside a section schema and looped section.blocks. In Horizon, blocks live as their own Liquid files. A section opts in, then renders children with {% content_for 'blocks' %}. Merchants can nest groups, headings, images and buttons in the editor without a custom section for every layout.
JSON templates still list up to 25 sections. Each section can still hold a large block tree. The practical difference is reuse. A product-card block can appear on the homepage, a collection grid and a related-products row without copying Liquid three times. That is good for merchants. It is also why a Dawn section named featured-product.liquid has nowhere to land.
Web components are the other surprise. Horizon leans on encapsulated UI for search, variants and cart. Encapsulation is good for Shopify's own code. It is hostile to older apps that query .product-form or bind to change on a select that no longer exists in the light DOM. App vendors have been shipping Horizon modules. Some have not. Your app list is part of the migration, not a post-launch ticket.
App blocks replace the old habit of dropping a review widget into product.liquid with a script tag. If a Horizon section does not accept @app blocks, the merchant cannot place that app in the editor. I cover that surface in Shopify app blocks for reviews and scripts. Theme-block nesting itself is a separate skill, which I wrote up as Shopify theme blocks vs section blocks explained.
How I run a Shopify Horizon theme migration
I run a Shopify Horizon theme migration as a duplicate-theme project with a frozen Dawn baseline. I never migrate the published theme in place. Shopify lets you preview an unpublished theme against live products. Use that. The live store stays on Dawn until the new theme passes a checkout, PDP and collection checklist.
First I export an inventory. Every custom section, every snippet that is not stock Dawn, every app embed, every metafield referenced in Liquid, every menu and every template JSON file. I screenshot the live homepage, PDP, collection, cart, search and article templates at desktop and a 390px phone. Those screenshots are the acceptance test. Horizon will not look identical. It has to sell the same SKUs with the same merchandising rules.
Second I stand up Horizon (or a Horizon-family theme if the brand needs a different visual starting point) as an unpublished copy. I rebuild templates in this order: product, collection, cart, index, then content templates. Product first because that is where money happens. Collection second because that is where crawl and internal links live. Cart third because a pretty homepage with a broken drawer is not a shop.
Third I re-wire metafields. Dawn stores often hang fit notes, care copy, badges and material data off product metafields. Horizon blocks read metafields through theme settings or dynamic sources. The metafield definitions usually survive. The Liquid that printed them does not. I map each metafield to a Horizon block or a custom theme block before I touch CSS.
Fourth I re-place apps as app blocks and app embeds, not as leftover script tags in theme.liquid. Reviews, loyalty, size charts and wishlists belong in the editor. Pixels belong in customer events or a web pixel, not in a Liquid comment from 2021.
Fifth I restyle. Horizon's spacing and type scale will not match a custom Dawn. That is expected. I do not try to clone Dawn pixel for pixel. I match the brand: photography crop, type hierarchy, PDP information order, and the mobile menu. Luxury jewellery and fashion stores live or die on image discipline, not on whether the old Dawn badge still uses the same class name.
Production checklist for the cutover
- Duplicate the live Dawn theme and label it
dawn-freeze-YYYY-MM-DD. Do not keep editing it. - Record Core Web Vitals from Search Console (field data, not only Lighthouse) for home, product and collection URL groups.
- List every installed app. Mark each as app block, app embed, checkout UI extension, or legacy script tag.
- Export metafield definitions and a sample of product, variant, collection and shop metafield values.
- Inventory custom sections and snippets. Decide keep (rebuild as a theme block), drop, or replace with a Horizon native block.
- Create an unpublished Horizon theme. Rebuild the product template first, then collection, cart, index.
- Place
@appblocks on PDP and collection where reviews, badges and loyalty used to inject via Liquid. - Test variant change, sold-out state, low inventory, back-in-stock, bundles and gift cards on real products.
- Test predictive search, filters, sort, pagination and empty collection states.
- Walk checkout on a development store or a Plus checkout preview. Theme migration does not replace checkout extensibility, but cart attributes and line-item properties must still arrive.
- Compare LCP on the hero and the PDP gallery. Horizon is not automatically faster. Heavy nested blocks and extra app blocks can make LCP worse.
- Give the merchant an editor walkthrough before publish. Horizon's nested blocks confuse people who learned Dawn's flat sections.
- Publish during a low-traffic window. Keep the Dawn freeze theme installed for a week so you can roll back.
- Re-check field INP and LCP after 28 days. Lab scores on publish day are not the result.
What breaks on a real catalogue
Custom Liquid that looped section.blocks is the first casualty. Horizon sections that opted into theme blocks do not render that loop the way Dawn did. If you paste old section code into Horizon, you get empty output or a block that cannot nest. Rebuild those as theme blocks or keep a hybrid section that still uses the old schema, knowing Shopify is not investing there.
JavaScript that assumed Dawn DOM is the second. Variant pickers inside web components will not fire the listeners your old product.js expected. Size guides, custom option UIs and "sticky add to cart" scripts are frequent failures. I rewrite those against the theme's documented events, or I replace them with a theme block plus a small script that does not pierce shadow DOM unless the component exposes a part.
CSS that targeted Dawn class names is the third. Horizon uses different markup. A 400-line custom.css full of .product__info-container overrides will do nothing useful and may still load. I delete it and restyle from the theme's CSS variables and theme.json-style settings where they exist.
Apps without a Horizon module are the fourth. Some review widgets still inject HTML into a Dawn snippet path that Horizon does not load. The widget vanishes. The merchant thinks reviews died. They did not. The hook did. Move them to app blocks.
Markets, B2B catalogues and translation files are the fifth. Dawn custom sections often hard-coded English strings. Horizon blocks should use locale files. If you skip this, a market switch looks like a broken theme.
Checkout is not in the theme. Plus stores that still had checkout.liquid customisations already had a separate project. Do not hide checkout work inside a Horizon ticket. It will slip.
How I measure a successful migration
I measure the migration on four layers: editor, speed, merchandising and revenue paths. Editor first, because a Horizon theme the merchant cannot edit will rot into another developer-only Dawn. Can they add a homepage row, swap a PDP badge, and place a review app block without a pull request? If no, the architecture failed.
Speed second. I keep the Dawn Search Console baselines. After publish I watch LCP for the PDP gallery (usually the LCP element on a store) and INP on collection filters and variant clicks. Horizon can improve INP if you drop jQuery apps. It can also worsen LCP if the new homepage nests three video blocks. I do not claim a speed win until field data agrees.
Merchandising third. Collection banners, related products, and the order of PDP blocks (gallery, price, variant, delivery, reviews) must still match how the brand sells. A Horizon default PDP that puts reviews above the fold on a jewellery SKU is a visual change with a conversion cost.
Revenue paths fourth. Add-to-cart, begin-checkout and purchase must still fire in GA4 with the same item IDs. Theme rebuilds are a classic way to lose the dataLayer. I test purchase on a real (refundable) order or a development store before I call it done.
I do not invent conversion percentages for a Horizon cutover. The one published storefront outcome I will cite is the Their Nibs Shopify rebuild, which was a full theme replacement on an ageing codebase: 31% more conversions and 48% more orders after launch. That was not a Horizon-specific number. It is what a disciplined rebuild can do when the old theme was the constraint. Horizon is only the 2026 way to do that rebuild.
Related work on this site
The same production layer shows up on the Shopify Plus jewellery storefront I shipped for Tamannaah Fine Jewellery: PDP behaviour, merchandising blocks, and photography that cannot fight checkout. Fashion operations work on Offporter is the other end of the spectrum, a Plus site that has to feel like infrastructure rather than a brochure. If your Horizon project is a converting rebuild rather than a greenfield, read the Their Nibs case next to this checklist.
FAQ
Do I have to do a Shopify Horizon theme migration in 2026?
No. Dawn still works and Shopify still maintains it. You need a Shopify Horizon theme migration when you are already rebuilding, when merchandisers cannot edit the Dawn theme, or when apps and custom sections have made the codebase too expensive to change. "Horizon is the new default" is not a conversion argument by itself.
Will a Shopify Horizon theme migration make my store faster?
Not automatically. A Shopify Horizon theme migration can reduce old jQuery and Dawn CSS, which may help INP. Nested blocks, extra app blocks and a heavier homepage can make LCP worse. Measure field Core Web Vitals before and after. Lab scores on a password page are not the result.
Can I copy Dawn sections into Horizon?
No. Horizon expects theme blocks and content_for, not Dawn's flat section.blocks loops. You can keep a hybrid section for a while, but pasted Dawn sections usually render empty or cannot nest. Rebuild the sections you still need as theme blocks.
What about apps during a Shopify Horizon theme migration?
Treat apps as a workstream. Replace script-tag injections with app blocks and app embeds. Test variant pickers, reviews, loyalty and search apps on Horizon before publish. An app that only ships a Dawn snippet will disappear on the new theme even though it is still installed.
Keep reading
Contact if you want this kind of work on a live store.