Theme Architecture
Directory layout
Section titled “Directory layout”| Directory | What lives there |
|---|---|
sections/ |
Full-width page components. Each has a {% schema %} and appears in the customizer. |
blocks/ |
Reusable components that slot into sections. Own schema, own settings. |
snippets/ |
Shared Liquid fragments rendered with {% render %}. No schema — they take parameters. |
frontend/ |
JS and CSS compiled by Vite. Alpine.js components live in frontend/entrypoints/js/alpine/. |
locales/ |
Translations. en.default.schema.json holds every customizer label. |
templates/ |
JSON files defining which sections appear on each page type. |
config/ |
Theme-wide settings. |
Sections vs. blocks vs. snippets
Section titled “Sections vs. blocks vs. snippets”The distinction matters, and it’s easy to get wrong.
Sections are the top-level building blocks a merchant adds to a page. They own layout and page-level settings — padding, background, colour.
Blocks are merchant-arrangeable content inside a section. They’re defined
once in blocks/ and referenced by type, never redefined per section.
Snippets are developer-level code reuse. If two blocks render the same markup, that markup belongs in a snippet both of them call.
Static blocks
Section titled “Static blocks”A static block is a theme block rendered individually rather than as part of the merchant-reorderable collection. It’s how a section pins a specific piece of content to a specific spot in its layout — a title above a product grid, say.
Each static block id may only be rendered once per section. When the same content needs to appear in two places (desktop bar and mobile drawer, for instance), capture the output first and echo the captured variable in both places:
{%- capture nav %}{% content_for 'block', type: 'header-nav', id: 'nav' %}{% endcapture -%}
<div class="desktop">{{ nav }}</div><div class="mobile">{{ nav }}</div>Build pipeline
Section titled “Build pipeline”Vite with vite-plugin-shopify. Assets are hashed on build and referenced
through snippets/vite-tag.liquid.
npm run dev # Vite + Shopify theme dev togethernpm run build # Production asset buildThe Shopify dev command runs with --theme-editor-sync, which pulls customizer
changes down into local templates/*.json files. Expect those files to
change under you while the dev server is running; they’re owned by the editor,
not by hand-editing.
Frontend
Section titled “Frontend”Alpine.js for interactivity — dropdowns, drawers, toggles. Components are
registered in frontend/entrypoints/js/alpine/.
Tailwind v4 with CSS-first config. The theme’s tokens live in
frontend/css/tailwind-theme.css under @theme. See
Conventions for the rules on colours and spacing.
React is used only for the cart drawer, mounted to #cart-drawer.