Skip to content
Log in

Theme layouts and pages

On this page

A layout is the outermost template that wraps page content in a complete HTML document. It typically contains the <html>, <head>, and <body> elements, along with common elements like the site header, footer, navigation, and asset includes.

Page templates render before the layout. The platform renders the page template into a string, then passes that string as the body_content variable to the layout. The layout wraps the pre-rendered page content — it does not “call” the page.

The default layout

The default layout is layouts/theme.liquid. All pages use this layout unless a page template specifies a different one. Here is a minimal layout:

```liquid

{%- default body_content: nil, csrf_meta_tags: nil, csp_meta_tag: nil -%} {%- default title: nil, meta_keywords: nil, meta_description: nil -%} {%- default sc_support: nil, theme_bar: nil, data: nil -%} {%- default controller: nil, action: nil, id: nil -%} {%- default theme_supplement_stylesheet: nil, theme_supplement_javascript: nil -%} <!doctype html>

{{ csrf_meta_tags }} {{ csp_meta_tag }} {% render "meta_data" %} {%- require "styles/theme.css" %} {{ theme_supplement_stylesheet }} {%- require "scripts/theme.js" %} {{ theme_supplement_javascript }} {{ sc_support }} <body id="{{ id }}" {{ data }}> {{ theme_bar }} {% render "header" %}
{% render "flash" %} {{ body_content }}
{% render "footer" %} </body>

```

Required layout variables

The platform passes these variables to layouts/theme.liquid. Declare all of them with {% default %} at the top of your layout to prevent undefined variable errors. Variables marked required will cause visible failures if omitted.

Variable Required Description
body_content YES The fully rendered page template output. Without this, the page appears blank.
csrf_meta_tags YES HTML <meta> tags containing CSRF tokens. Without this, all form submissions fail.
csp_meta_tag YES Content Security Policy <meta> tag.
sc_support YES Platform support scripts.
theme_bar YES Theme editor and preview bar HTML. Without this, the theme editor breaks.
theme_supplement_stylesheet YES <link> tag for custom theme CSS (theme-supplement.css). Without this, custom theme styles do not load.
theme_supplement_javascript YES <script> tag for custom theme JS (theme-supplement.js). Without this, custom theme scripts do not load.
title no Page title, auto-generated per page type (product name, article title, store name). Used by the meta_data snippet.
meta_keywords no SEO keywords for the page.
meta_description no SEO description for the page.
controller no Name of the controller handling the request (for example products, carts). Useful for body classes or conditional logic.
action no Controller action name (for example show, index).
id no Page identifier string, formatted as SC-{controller}-{action} (for example SC-products-show). Intended for the <body> element’s id attribute.
data no Extra data attributes for the <body> element.
format no Response format if non-HTML (for example txt, json).

:::warning Always output {{ body_content }}, {{ csrf_meta_tags }}, and {{ theme_bar }} in your layout. Omitting any of these causes visible failures: blank pages, broken forms, or a broken theme editor. :::

Rendering order

  1. The Liquid controller’s {% before %} phase runs.
  2. The page template renders into a string.
  3. The rendered string is passed as body_content to layouts/theme.liquid.
  4. The layout renders, outputting {{ body_content }} where the page content should appear.
  5. The Liquid controller’s {% after %} and {% final %} phases run.

Multiple layouts

You can define additional layouts for distinct sections of your site. For example, an account layout that adds a sidebar:

```liquid

{%- comment -%} layouts/account.liquid {%- endcomment -%}

{% render "account/menu" %}
{{ yield }}

```

Secondary layouts render within the main theme.liquid. The {{ yield }} variable is where the page content appears inside the secondary layout, while the secondary layout’s output becomes body_content in the main layout.

To use a non-default layout, add a {% layout %} tag at the top of the page template:

```liquid

{% layout “account” %} ```

If no {% layout %} tag is present, theme.liquid is used.

Page routing table

Page templates render for specific URL patterns. The file name determines the route mapping.

Core pages

Page template URL pattern Context variable
home.liquid / current_page
product.liquid /products/:slug current_product
products.liquid /products, /products/category/:path current_search, current_product_category
product_category.liquid /products/category/:path current_product_category, current_search
cart.liquid /cart current_cart
checkout.liquid /checkout, /checkout/:step current_cart, current_checkout_step
order.liquid /orders/:token current_order
page.liquid /pages/:path current_page
article.liquid /articles/:path current_article
article_category.liquid /articles/category/:path current_article_category
search.liquid /search current_search
account.liquid /account, /account/:section current_customer, current_account
location.liquid /locations/:slug current_location
locations.liquid /locations (locations collection)
not_found.liquid any unmatched URL error
maintenance.liquid when store is in maintenance mode
form_submission.liquid /form-submissions/:id current_form_submission
voucher.liquid /vouchers/:code current_voucher
subscription.liquid /subscriptions/:id current_subscription

Authentication pages

Authentication pages live in the pages/auth/ subdirectory:

Page template URL pattern Purpose
auth/login.liquid /login Login form
auth/register.liquid /register Registration form
auth/password/forgot.liquid /password/forgot Forgot password form
auth/password/reset.liquid /password/reset Reset password form
auth/confirmation/pending.liquid /confirmation/pending Email confirmation pending
auth/confirmation/resend.liquid /confirmation/resend Resend confirmation email
auth/invitation/accept.liquid /invitation/accept Accept invitation
auth/invitation/pending.liquid /invitation/pending Invitation pending
auth/missing_details.liquid /missing-details Complete profile after login

Global variables

These variables are available on every page template:

Variable Type Description
current_store StoreDrop Current store configuration
current_cart CartDrop Shopping cart
current_customer ContactDrop Logged-in customer (nil if not logged in)
current_account AccountDrop Logged-in customer’s account
current_request RequestDrop HTTP request info (path, params, etc.)
current_flash FlashDrop Flash messages (notice, alert, error)
all_products Collection All products
all_pages Collection All content pages
all_articles Collection All articles
all_product_categories Collection All product categories
all_article_categories Collection All article categories
all_menus Collection Navigation menus
all_content_blocks Collection Content blocks
all_media Collection Media files
session_variables Hash Session variables (set with {% session %})
theme_variables Hash Theme variables

Checkout steps

The checkout page uses current_checkout_step to determine which step to display:

Step Value Description
Customer information "customer_information" Collect customer details
Shipping information "shipping_information" Select shipping method
Accept terms "accept_terms" Terms and conditions
Payment information "payment_information" Payment method and submission

```liquid

{% case current_checkout_step %} {% when “customer_information” %} {% form “checkout-customer-information” %} {% render “checkout/customer_information/form”, form: form %} {% endform %} {% when “shipping_information” %} {% form “checkout-shipping-information” %} {% render “checkout/shipping_information/form”, form: form %} {% endform %} {% when “accept_terms” %} {% form “checkout-accept-terms” %} {% render “checkout/accept_terms/form”, form: form %} {% endform %} {% when “payment_information” %} {% component “checkout/payment_information/page”, reload: “sc.voucher-applied sc.voucher-removed” %} {% endcase %} ```

:::note The payment information step must use {% component %}, not a {% form %} block. The component handles the payment provider JavaScript that powers the payment fields. :::

Account sections

The account page uses current_request.params.section to route to different account areas:

Section URL Description
(default) /account Profile overview
orders /account?section=orders Order history
carts /account?section=carts Saved carts
fulfillments /account?section=fulfillments Fulfillment tracking
subscriptions /account?section=subscriptions Subscriptions
account_credits /account?section=account_credits Account credits
account_points /account?section=account_points Loyalty points
product_approvals /account?section=product_approvals Product approval requests
credentials /account?section=credentials Change password
contact /account?section=contact Edit contact information
shipping /account?section=shipping Shipping addresses
billing /account?section=billing Billing addresses

Content-type variants

Some pages support multiple output formats. The variant file renders when the corresponding format is requested:

File Content type Example URL
page.liquid HTML /pages/about
page.json.liquid JSON /pages/about.json
page.xml.liquid XML /pages/about.xml
page.csv.liquid CSV /pages/about.csv
page.md.liquid Markdown /pages/about.md
page.text.liquid Plain text /pages/about.txt

Articles support all the same variants.

Home page

The home page template typically renders the content blocks configured for the store’s home page:

```liquid

{% if current_page != blank %} {{ current_page.body_content }} {% else %}

Configure a home page in your store settings.

{% endif %} ```

The home page is linked to a content page in the store configuration. That content page’s blocks (slideshows, featured products, text sections, and so on) are rendered via body_content.

:::tip current_page.body_content (used in pages/home.liquid) and body_content (used in layouts/theme.liquid) are different variables. The first renders the CMS content blocks on the page object. The second is the fully rendered page template output passed to the layout. :::

Was this article helpful?

Was this article helpful?