{"title":"Theme structure and file organization","slug":"theme-structure","url":"https://support.storeconnect.com/articles/theme-structure","url_markdown":"https://support.storeconnect.com/articles/theme-structure.md","subtitle":null,"summary":"A StoreConnect theme is a directory of Liquid template files organized into subdirectories by purpose, with the directory layout, naming conventions, content-type variants, and the two-tier base/client override system.","type":"Developer_Documentation","video_url":"","keywords":"theme structure, theme files, liquid templates, directory layout, theme override, base theme, client theme, snake_case, content type variants, theme organization","last_modified":"2026-08-21T07:12:35+0000","body_markdown":"A StoreConnect theme is a collection of Liquid template files stored in a structured directory hierarchy. During development, themes are synced to the platform from files on disk. Understanding the directory layout is essential before writing any templates.\n\n## Directory structure\n\n```\n\nmy-theme/\n├── layouts/              # Layout templates (required)\n│   ├── theme.liquid      # Main layout (default)\n│   └── account.liquid    # Account section layout\n│\n├── pages/                # Page templates (required)\n│   ├── home.liquid\n│   ├── product.liquid\n│   ├── products.liquid\n│   ├── cart.liquid\n│   ├── checkout.liquid\n│   ├── order.liquid\n│   ├── account.liquid\n│   ├── page.liquid\n│   ├── article.liquid\n│   ├── search.liquid\n│   ├── not_found.liquid\n│   └── auth/\n│       ├── login.liquid\n│       └── register.liquid\n│\n├── snippets/             # Reusable partial templates\n│   ├── header.liquid\n│   ├── footer.liquid\n│   └── ...\n│\n├── blocks/               # Content block templates\n│   ├── text.liquid\n│   ├── image.liquid\n│   └── ...\n│\n├── components/           # Reloadable async component templates\n│   ├── cart.liquid\n│   └── ...\n│\n├── controllers/          # Liquid controller templates\n│\n├── helpers/              # Shared logic templates\n│\n├── resources/            # Static assets (CSS, JS, images, fonts)\n│   └── src/\n│       ├── scripts/\n│       └── styles/\n│\n├── translations/         # Locale files\n│   └── en.default.json\n│\n├── variables.json        # Theme configuration variables\n└── assets.json           # Asset build configuration\n```\n\n## Required directories\n\n### `layouts/`\n\nLayout templates wrap every page in a complete HTML document. Every theme must include at least one layout: `layouts/theme.liquid`. This file provides the `\u003chtml\u003e`, `\u003chead\u003e`, and `\u003cbody\u003e` elements, along with the header, footer, and asset includes common to all pages.\n\nSee [Theme layouts and pages](theme-layouts-and-pages) for detailed layout requirements.\n\n### `pages/`\n\nPage templates render for specific URL routes. The file name determines which route the template handles. At a minimum, a theme should include templates for the key routes a store visitor will encounter (home, product, cart, checkout).\n\nSee [Theme layouts and pages](theme-layouts-and-pages) for the full routing table.\n\n## Optional directories\n\n### `snippets/`\n\nSnippets are reusable template fragments included with `{% render \"snippet_name\" %}`. Organize them into subdirectories for clarity:\n\n```\n\nsnippets/\n├── header.liquid\n├── footer.liquid\n├── products/\n│   ├── card.liquid\n│   └── price.liquid\n└── shared/\n    └── loader.liquid\n```\n\nReference nested snippets with their path: `{% render \"products/card\" %}`.\n\n### `blocks/`\n\nContent block templates define how structured content blocks render on pages. Block types include `text`, `image`, `slideshow`, `html`, `video`, `container`, and others. Blocks are configured in the CMS and rendered on pages via `{{ page.body_content }}`.\n\n### `components/`\n\nComponents are template fragments that reload asynchronously without a full page refresh. They respond to JavaScript events dispatched on the document. Use them for parts of the UI that must stay live — such as the cart badge in the header.\n\n\n```liquid\n\n{% component \"cart\", reload: \"sc.cart-updated\" %}\n```\n\n\nComponents can also be organized into subdirectories:\n\n```\n\ncomponents/\n├── cart.liquid\n├── cart-menu.liquid\n└── checkout/\n    ├── payment_information/\n    │   └── page.liquid\n    └── vouchers.liquid\n```\n\nSee [Theme snippets, blocks, and components](theme-snippets-blocks-components) for full details.\n\n### `controllers/`\n\nLiquid controllers provide server-side logic for pages. They can run before or after a page renders, modify variables, handle redirects, and perform actions like updating the cart.\n\n### `helpers/`\n\nHelper templates contain shared logic used by controllers or other templates. They are included like snippets but serve as reusable logic units rather than UI fragments.\n\n### `resources/`\n\nStatic assets served to the browser — JavaScript, CSS, fonts, and images. The structure follows a `src/` → `dist/` build convention:\n\n```\n\nresources/\n└── src/\n    ├── scripts/\n    │   ├── theme/        # Core theme scripts\n    │   └── packs/        # Additional script bundles\n    ├── styles/\n    │   ├── theme/        # Core theme styles\n    │   └── packs/        # Additional style bundles\n    └── files/            # Static files (images, fonts, etc.)\n```\n\nLoad assets in templates with `{% require \"scripts/theme.js\" %}` and reference static files with `{{ \"logo.png\" | asset_url }}`.\n\nSee [Theme assets and styling](theme-assets-and-styling) for the full reference.\n\n### `translations/`\n\nJSON files containing translation strings keyed by dot-notation paths. The default locale file is `en.default.json`. Access translations with the `t` filter:\n\n\n```liquid\n\n{{ \"products.show.add_to_cart\" | t }}\n```\n\n\n## Theme variables\n\nTheme variables are key-value settings stored against the theme in StoreConnect. They are accessible in any template via the `theme_variables` object:\n\n\n```liquid\n\n{% assign per_page = theme_variables[\"products.per_page\"] %}\n{% assign image_ratio = theme_variables[\"images.ratio.width\"] %}\n```\n\n\nThe built-in theme provides default values (for example `products.per_page: 12`). Custom theme variables override these defaults.\n\nSee [Theme variables](theme-variables) for the full variable reference.\n\n## File naming conventions\n\n- Template files use the `.liquid` extension.\n- File names and directory names use `snake_case` (for example `product_category.liquid`).\n- Content-type variants use dot notation before `.liquid` (for example `article.json.liquid`, `page.xml.liquid`).\n- Translation files use the pattern `{locale}.default.json`.\n\n## Content-type variants\n\nSome pages support multiple output formats. The variant file is served when the corresponding format is requested:\n\n| File | Renders for |\n|------|-------------|\n| `page.liquid` | HTML requests (`/pages/about`) |\n| `page.json.liquid` | JSON requests (`/pages/about.json`) |\n| `page.xml.liquid` | XML requests (`/pages/about.xml`) |\n| `page.csv.liquid` | CSV requests (`/pages/about.csv`) |\n| `page.md.liquid` | Markdown requests |\n| `page.text.liquid` | Plain text requests |\n\nArticles support all the same variants.\n\n## The base/client override system\n\nStoreConnect uses a two-tier theme system:\n\n1. **Base theme** — The default theme provided by StoreConnect, containing all standard templates.\n2. **Client theme** — A custom theme that overrides specific templates from the base.\n\nWhen rendering a page, the platform resolves templates in this order:\n\n1. Look in the client theme for the requested template.\n2. If not found, fall back to the base theme.\n\nThis means a client theme only needs to contain the templates it wants to customize. A minimal override might look like this:\n\n```\n\nmy-client-theme/\n├── pages/\n│   └── product.liquid    # Custom product page\n└── snippets/\n    └── header.liquid     # Custom header\n```\n\nAll other pages, snippets, and blocks will use the base theme versions automatically.\n\n:::tip\nStart with the smallest possible override. Add templates to your client theme only when you need to change the default behavior. Fewer custom files means less maintenance as the base theme evolves.\n:::"}