How rendering works
Every storefront page goes through the same steps. Knowing them tells you which file to change.
1. The request picks a store, a theme and a template
Section titled “1. The request picks a store, a theme and a template”The domain picks the store. The store’s live theme draws the page, unless a staff member is previewing another theme or editing in the visual editor.
The URL picks the page type and its template:
| URL | Page type | Template |
|---|---|---|
/ |
index |
templates/index.json |
/products/<handle> |
product |
templates/product.json |
/collections/<handle> |
collection |
templates/collection.json |
/collections |
list-collections |
templates/list-collections.json |
/pages/<handle> |
page |
templates/page.json |
/blogs/<blog>, /blogs/<blog>/<article> |
blog, article |
templates/blog.json, templates/article.json |
/search |
search |
templates/search.json |
/cart |
cart |
templates/cart.json |
/custom/<name> |
custom_page |
custom_pages/<name>.liquid |
/password |
password |
templates/password.json |
| anything else | 404 |
templates/404.json |
A product, collection or page can use an alternate template: templates/product.gift.json is used by products whose template is set to “gift” in admin. Products also take ?view=gift, which is how quick-view popups load a lighter template.
Pages in a language other than the store’s primary one have a prefix: /ar/products/…. The prefix is handled for you: routes, url properties and the url setting all include it.
2. The template lists sections
Section titled “2. The template lists sections”A JSON template is data the visual editor writes: which sections the page has, their settings and blocks, and their order.
{ "sections": { "main": { "type": "main-product", "blocks": { "title": { "type": "product-title" } }, "block_order": ["title"] }, "related": { "type": "related-products", "settings": { "limit": 4 } } }, "order": ["main", "related"]}Each entry renders sections/<type>.liquid with a section object holding its settings and blocks, wrapped in an element:
<section id="shopify-section-template--main" class="shopify-section">…</section>A Liquid template (templates/page.faq.liquid) is rendered as is, without sections the merchant can arrange.
3. Sections render blocks
Section titled “3. Sections render blocks”A section loops over section.blocks, or outputs its theme blocks with {% content_for 'blocks' %}. Blocks can hold blocks, up to 8 levels deep.
4. The layout wraps the result
Section titled “4. The layout wraps the result”The template’s output becomes content_for_layout inside layout/theme.liquid (or the layout the template names). The layout draws the <head>, renders the header and footer section groups with {% sections 'header-group' %}, and must output:
{{ content_for_header }}in<head>: meta tags, hreflang links, analytics and the editor bridge.{{ content_for_layout }}in<body>.
5. The HTML is sent, and cached
Section titled “5. The HTML is sent, and cached”Pages of the live theme are cached and refreshed when the merchant changes something that appears on them. Previews and the visual editor are never cached.
When something goes wrong
Section titled “When something goes wrong”A Liquid error doesn’t break the page. In previews and the editor the error is shown where it happened (Liquid error (sections/hero.liquid): …); on the live store it becomes an HTML comment. The code editor won’t save a syntax error to the live theme.
A page also has limits: 2 seconds to render, 10,000 iterations per loop and 200 sections.
Was this page helpful?

