Ready to maximize your revenue?Book a Demo
TOPCODE
Online Store 2

Online Store 2.0: what changed for theme developers

Last updated on June 2, 2026

Online Store 2.0: what changed for theme developers

TOPCODE

When Shopify shipped Online Store 2.0 at Unite 2021, the announcement was framed around merchant benefits: drag-and-drop on every page, no-code customisation everywhere. But the engineering implications for theme developers were equally significant. The template format changed, the way sections are organised changed, and the mechanism for pulling structured merchant data into theme files changed entirely. If you built themes before June 2021, some of what you know is now a legacy pattern. Here's a clear-eyed account of exactly what changed and what it means for your workflow.

Section groups replaced static layouts

In the original Online Store, sections existed but were only usable on the homepage. Every other page — collections, products, blogs, the cart — used a static layout/theme.liquid with hard-coded {% section 'header' %} and {% section 'footer' %} calls. Merchants couldn't reorder those sections in the theme editor; they were fixed.

OS 2.0 introduced section groups: named groups that correspond to layout positions — header, footer, overlay, aside — that are declared in layout/theme.liquid with {% sections 'header-group' %}. The sections within each group are stored in a separate JSON data file in config/settings_data.json and are editable in the customiser. Merchants can now add announcement bars, navigation menus, and promotional banners to the header section group without any code changes.

For theme developers, the migration implication is to replace {% section 'header' %} in your layout with {% sections 'header-group' %} (note the plural sections tag) and create corresponding JSON group definition files. Existing per-section settings are preserved during this migration.

JSON templates are the new starting point

Before OS 2.0, template files like templates/product.liquid were pure Liquid. If you wanted sections on the product page, you had to explicitly call {% section 'product-template' %} from inside the template file and define a special {% schema %} block to enable the section in the editor. It was convoluted.

OS 2.0 replaces templates/product.liquid with templates/product.json. This JSON file declares which sections are used in the template and stores their initial settings. The actual Liquid rendering logic moves to sections/main-product.liquid. Because the template is just JSON data, Shopify can give every product page its own layout configuration — a merchant can create a second product template templates/product.feature.json for a full-bleed hero product page, and assign it selectively from the product detail view.

templates/product.jsonjson
{
  "sections": {
    "main": {
      "type": "main-product",
      "blocks": {
        "title_block": { "type": "title",       "settings": {} },
        "price_block": { "type": "price",       "settings": {} },
        "form_block":  { "type": "buy_buttons", "settings": { "show_dynamic_checkout": true } },
        "desc_block":  { "type": "description", "settings": {} }
      },
      "block_order": ["title_block", "price_block", "form_block", "desc_block"],
      "settings": {}
    },
    "recommendations": {
      "type": "product-recommendations",
      "settings": { "heading": "You might also like", "limit": 4 }
    }
  },
  "order": ["main", "recommendations"]
}

The JSON template format is also what enables per-page template assignment. In the Shopify admin, merchants navigate to a product and select a template from a dropdown. The theme ships with one product.json by default; each additional product.*.json file shows up as another option.

Metafield-aware blocks via dynamic sources

OS 2.0 sections can expose block settings as "dynamic sources". This means that a block setting of type text or richtext in a product section can be wired by a merchant to a metafield like product.metafields.custom.ingredients_summary without touching a line of code. The theme editor shows a "Connect dynamic source" button next to the setting and merchants can pick from available metafields for the current resource.

For theme developers, this changes how you should think about section settings. In OS 1.0, you'd add a hardcoded {{ section.settings.custom_text }} and accept that merchants would paste the same content into each page's section settings. Now you define the same setting but merchants can bind it to a metafield once, and the content populates dynamically per-product from the metafield value. This is sometimes called "metafield passthrough".

To support this, ensure your section schema uses precise setting types. A richtext type setting will accept dynamic sources from rich_text_field metafields; an image_picker setting will accept dynamic sources from file_reference metafields pointing to images. Type mismatches are silently ignored — the setting falls back to its static value.

Migration path

There is no automated migration tool. The Shopify CLI can generate a new OS 2.0 theme scaffold from Dawn, but converting an existing theme is a manual process. The common approach is to work page-type by page-type. Start with the product template: extract the Liquid rendering logic from templates/product.liquid into sections/main-product.liquid, replace the template file with templates/product.json pointing to your new section, and test. Then repeat for collection, page, blog, and article templates.

The sections/ directory should be broken into meaningful, single-purpose files. Dawn's structure is a good reference: main-product.liquid, main-collection-product-grid.liquid, main-blog.liquid — one section per primary content area per template type. Reusable components (image banners, testimonial carousels, logo lists) live as standalone sections that can be added to any template.

Should you migrate yet?

If you're building a new theme from scratch: yes, always use OS 2.0 architecture. There is no reason to start with the old pattern. Use Dawn as your starting point or scaffolding reference.

If you're maintaining an existing theme for an active store: migrate when you have a dedicated sprint for it — not as a side-of-desk task. The changes are not strictly breaking (old themes continue to work), but any new merchant who expects drag-and-drop on product pages will be disappointed by an OS 1.0 theme. The practical trigger is usually when a merchant asks for a new layout on product or collection pages — at that point, the migration pays for itself in one project.

The platform will continue adding features that require OS 2.0 themes — metaobject rendering in the theme editor, deeper dynamic source integrations, and future AI-powered customisation tools all assume the JSON template architecture. Staying on OS 1.0 patterns means opting out of the roadmap, not just the current feature set.

Blocks: the fundamental unit of page composition

Understanding blocks is essential to grasping why OS 2.0 is architecturally superior for both developers and merchants. In OS 1.0, a product section might render the title, price, variant selector, and buy button in a fixed sequence set by the Liquid file. A merchant wanting to move the description after the buy buttons — a common conversion rate optimisation request — had to hire a developer to change the Liquid.

In OS 2.0, that same product section declares block types in its schema — title, price, variant_picker, buy_buttons, description. The order in which those blocks render is stored in the JSON template file as block_order. A merchant drags the description block below buy_buttons in the customiser. Shopify updates the block_order array in the JSON template. The Liquid section iterates section.blocks and renders each block in the stored order. No code change required.

Blocks can also be added and removed by merchants without code changes. If a merchant doesn't need a size chart on a particular product, they remove the size chart block from the template for that product. The block still exists in the section's schema as an available option; it simply isn't included in that product's JSON template block list. This granularity of control — available at the product level, not just the theme level — is one of the most underappreciated capabilities OS 2.0 unlocked.

Performance implications of OS 2.0

The Dawn reference theme that ships with OS 2.0 was rebuilt from the ground up with performance as a primary constraint. It uses no JavaScript framework, relies on Web Components for interactive elements, and employs modern image APIs (image_url filter with srcset generation). Lighthouse scores on a default Dawn install are consistently in the 90s on desktop and high 70s to low 80s on mobile — a significant improvement over typical OS 1.0 themes that accumulated years of third-party script bloat.

OS 2.0 also enables deferred loading of app block assets. Because app blocks are loaded conditionally — only when a merchant has added a specific block to a page — their CSS and JS assets load only on pages that use them. In the OS 1.0 Script Tag model, every app's scripts loaded on every page of the store, regardless of whether that page used the app. The reduction in extraneous script loading is a measurable performance gain for stores with five or more installed apps.

Senior Shopify Engineer

Frances Chen

Keep reading