Use this guide when creating, moving, or connecting files in an Online Store 2.0 theme. Shopify's current documentation is the source of truth; confirm unfamiliar or recently added APIs there before coding.
Use the supported directory model
A theme may use assets, blocks, config, layout, locales, sections, snippets, and templates. Customer templates live under templates/customers, and metaobject templates can live under templates/metaobject. Do not invent parallel source directories inside the uploaded theme. Build tools may keep source elsewhere, but their output must land in Shopify's supported structure.
layout/theme.liquidis the storefront shell. It must rendercontent_for_headerinside<head>andcontent_for_layoutin the body.templates/*.jsoncompose pages from sections and let merchants reorder or configure them.- Liquid templates remain appropriate for layouts and Shopify template types that do not support JSON.
sections/*.liquidare merchant-configurable page modules. Section groups such asheader-group.jsonandfooter-group.jsoncompose global areas.blocks/*.liquidare reusable theme blocks that sections can accept with@themeblocks.snippets/*.liquidare parameterized, reusable render units. They do not appear in the theme editor.config/settings_schema.jsondefines global theme settings.config/settings_data.jsoncontains merchant state and should not be overwritten casually.locales/*.jsonand*.schema.jsonhold storefront and theme-editor translations.assetsholds CSS, JavaScript, fonts, and static media that belong to the theme.
Compose JSON templates safely
A JSON template contains a sections object and an order array. Each order entry must match a key in sections. A section entry needs a valid type matching a section filename without .liquid; its optional settings and blocks must match that section's schema.
Do not treat generated JSON as comments-tolerant configuration. It must parse as strict JSON. Preserve merchant-created template instances unless the task explicitly replaces the full page composition.
Section groups follow the same composition idea and are rendered from a Liquid layout with the sections tag:
{% sections 'header-group' %}
<main id="MainContent" role="main">
{{ content_for_layout }}
</main>
{% sections 'footer-group' %}
Use {% section 'name' %} only for a static section call. A static section is not managed like a JSON-template section instance.
Keep ownership boundaries explicit
Theme code owns storefront presentation and cart interactions. Shopify owns checkout unless the task explicitly targets an allowed checkout extension surface. Do not imitate checkout, collect payment details in theme code, or bypass Shopify's cart and checkout routes.
Work in an unpublished duplicate. Preserve {{ content_for_header }}, app blocks, app embeds, analytics hooks, and merchant settings when adapting an existing theme. Never replace settings_data.json or publish a theme without explicit approval.