Shopify theme file structure: what every folder does
Nine folders, each with a specific job. What goes where, and the files you must not delete.
7 min read · Themes & storefront ·
A Shopify theme is a fixed folder structure. Shopify looks for specific files in specific places, so the layout isn't a convention you can improve on — it's the contract. Here's what each folder does and what breaks if you get it wrong.
The folders
`` layout/ theme.liquid, and optionally checkout or password layouts templates/ one file per page type, mostly JSON sections/ configurable page sections, plus section group JSON snippets/ reusable Liquid fragments blocks/ reusable blocks available across sections assets/ CSS, JS, images, fonts config/ settings_schema.json and settings_data.json locales/ translatable strings, one file per language ``
layout/
theme.liquid wraps every page. It contains the <html> shell, and two objects Shopify requires:
{{ content_for_header }}in the<head>— Shopify injects scripts, meta and app code here.{{ content_for_layout }}in the<body>— the rendered template goes here.
Delete or move either and the store breaks in ways that are hard to diagnose. Everything global — header, footer, meta tags, font loading — lives here or in section groups referenced from here.
templates/
One file per page type: index, product, collection, cart, page, blog, article, search, 404, list-collections, customers/*.
Most are now JSON templates that list which sections render and in what order. Liquid templates still work and are right for pages that genuinely aren't merchant-configurable.
Alternate templates are how you get variation: product.bundle.json sits alongside product.json, and a merchant assigns it to specific products from the admin. This is the correct way to give twenty products a different layout — far better than an {% if %} on product type inside one template.
sections/
Configurable page sections, each with its schema. Also holds section group JSON files for header, footer and other areas. Covered in sections and blocks.
snippets/
Reusable Liquid fragments with no schema and no merchant settings — a product card, a price display, an icon. Rendered with {% render 'name', param: value %}, which gives them an isolated scope.
The practical rule: if a merchant configures it, it's a section. If a developer reuses it, it's a snippet.
blocks/
Reusable block definitions that multiple sections can accept, rather than each section redeclaring the same block type. Useful once a theme has grown enough that you're copying block schemas between sections.
assets/
Every static file. Referenced with the asset_url filter — never hard-code a path:
``liquid {{ 'base.css' | asset_url | stylesheet_tag }} {{ 'cart.js' | asset_url | script_tag }} ``
Assets are served from Shopify's CDN. There's no build step required, though most serious theme work uses one locally and commits the output. Keep an eye on what accumulates here: unused files from a previous design are dead weight that nobody notices, and they're on the performance checklist.
config/
settings_schema.json defines the global theme settings a merchant sees under Theme settings. settings_data.json holds their chosen values — it's data, not code, and overwriting it wipes their configuration. See theme settings and schema.
locales/
Every user-facing string, one JSON file per language, accessed with the t filter. Strings hard-coded into templates cannot be translated and have to be found and extracted later — which is why localisation is so much cheaper to plan for than to retrofit.
Files ending .schema.json translate the theme editor's own labels, so a merchant working in another language sees your settings in theirs.
Files to be careful with
| File | Why |
|---|---|
layout/theme.liquid | Contains the required injection points |
config/settings_data.json | The merchant's settings — data, not code |
templates/*.json | Overwriting resets a merchant's page layout |
locales/*.json | Removing keys breaks strings elsewhere |
All four are reasons to work on an unpublished duplicate rather than the live theme, and to keep the whole thing in version control through the CLI.
The structure is rigid, and that's a feature. Any Shopify developer can open any theme and know where to look — as long as nobody got creative.
Is this the problem you’re looking at?
Send me the link to your store and a line about what is going wrong. You get a straight answer within one business day — no pitch, no obligation.
mario@clicksandcarts.coOr see what I do around Shopify: services, work beyond the theme, selected work.