Theme structure and file organization
On this page
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.
Directory structure
```
my-theme/ ├── layouts/ # Layout templates (required) │ ├── theme.liquid # Main layout (default) │ └── account.liquid # Account section layout │ ├── pages/ # Page templates (required) │ ├── home.liquid │ ├── product.liquid │ ├── products.liquid │ ├── cart.liquid │ ├── checkout.liquid │ ├── order.liquid │ ├── account.liquid │ ├── page.liquid │ ├── article.liquid │ ├── search.liquid │ ├── not_found.liquid │ └── auth/ │ ├── login.liquid │ └── register.liquid │ ├── snippets/ # Reusable partial templates │ ├── header.liquid │ ├── footer.liquid │ └── … │ ├── blocks/ # Content block templates │ ├── text.liquid │ ├── image.liquid │ └── … │ ├── components/ # Reloadable async component templates │ ├── cart.liquid │ └── … │ ├── controllers/ # Liquid controller templates │ ├── helpers/ # Shared logic templates │ ├── resources/ # Static assets (CSS, JS, images, fonts) │ └── src/ │ ├── scripts/ │ └── styles/ │ ├── translations/ # Locale files │ └── en.default.json │ ├── variables.json # Theme configuration variables └── assets.json # Asset build configuration ```
Required directories
layouts/
Layout templates wrap every page in a complete HTML document. Every theme must include at least one layout: layouts/theme.liquid. This file provides the <html>, <head>, and <body> elements, along with the header, footer, and asset includes common to all pages.
See Theme layouts and pages for detailed layout requirements.
pages/
Page 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).
See Theme layouts and pages for the full routing table.
Optional directories
snippets/
Snippets are reusable template fragments included with {% render "snippet_name" %}. Organize them into subdirectories for clarity:
```
snippets/ ├── header.liquid ├── footer.liquid ├── products/ │ ├── card.liquid │ └── price.liquid └── shared/ └── loader.liquid ```
Reference nested snippets with their path: {% render "products/card" %}.
blocks/
Content 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 }}.
components/
Components 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.
```liquid
{% component “cart”, reload: “sc.cart-updated” %} ```
Components can also be organized into subdirectories:
```
components/ ├── cart.liquid ├── cart-menu.liquid └── checkout/ ├── payment_information/ │ └── page.liquid └── vouchers.liquid ```
See Theme snippets, blocks, and components for full details.
controllers/
Liquid 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.
helpers/
Helper 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.
resources/
Static assets served to the browser — JavaScript, CSS, fonts, and images. The structure follows a src/ → dist/ build convention:
```
resources/ └── src/ ├── scripts/ │ ├── theme/ # Core theme scripts │ └── packs/ # Additional script bundles ├── styles/ │ ├── theme/ # Core theme styles │ └── packs/ # Additional style bundles └── files/ # Static files (images, fonts, etc.) ```
Load assets in templates with {% require "scripts/theme.js" %} and reference static files with {{ "logo.png" | asset_url }}.
See Theme assets and styling for the full reference.
translations/
JSON files containing translation strings keyed by dot-notation paths. The default locale file is en.default.json. Access translations with the t filter:
```liquid
{{ “products.show.add_to_cart” | t }} ```
Theme variables
Theme variables are key-value settings stored against the theme in StoreConnect. They are accessible in any template via the theme_variables object:
```liquid
{% assign per_page = theme_variables[“products.per_page”] %} {% assign image_ratio = theme_variables[“images.ratio.width”] %} ```
The built-in theme provides default values (for example products.per_page: 12). Custom theme variables override these defaults.
See Theme variables for the full variable reference.
File naming conventions
- Template files use the
.liquidextension. - File names and directory names use
snake_case(for exampleproduct_category.liquid). - Content-type variants use dot notation before
.liquid(for examplearticle.json.liquid,page.xml.liquid). - Translation files use the pattern
{locale}.default.json.
Content-type variants
Some pages support multiple output formats. The variant file is served when the corresponding format is requested:
| File | Renders for |
|---|---|
page.liquid |
HTML requests (/pages/about) |
page.json.liquid |
JSON requests (/pages/about.json) |
page.xml.liquid |
XML requests (/pages/about.xml) |
page.csv.liquid |
CSV requests (/pages/about.csv) |
page.md.liquid |
Markdown requests |
page.text.liquid |
Plain text requests |
Articles support all the same variants.
The base/client override system
StoreConnect uses a two-tier theme system:
- Base theme — The default theme provided by StoreConnect, containing all standard templates.
- Client theme — A custom theme that overrides specific templates from the base.
When rendering a page, the platform resolves templates in this order:
- Look in the client theme for the requested template.
- If not found, fall back to the base theme.
This means a client theme only needs to contain the templates it wants to customize. A minimal override might look like this:
```
my-client-theme/ ├── pages/ │ └── product.liquid # Custom product page └── snippets/ └── header.liquid # Custom header ```
All other pages, snippets, and blocks will use the base theme versions automatically.
:::tip Start 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. :::
Was this article helpful?
Thanks for your feedback! It helps us improve our docs.