Liquid Tutorial

theme.liquid Layout

Source: Coding with Robby

The Root HTML Document

layout/theme.liquid is the outermost template. Every page renders inside it. {{ content_for_layout }} is where template sections appear; {{ content_for_header }} is mandatory — Shopify injects app scripts, analytics, and dynamic checkout buttons there.

Production-ready theme.liquid skeleton
<!doctype html>
<html class="no-js" lang="{{ request.locale.iso_code }}">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <meta name="theme-color" content="{{ settings.color_primary }}">

  <title>
    {{ page_title }}
    {%- if current_tags %} &ndash; tagged "{{ current_tags | join: ', ' }}"{% endif -%}
    {%- if current_page != 1 %} &ndash; Page {{ current_page }}{% endif -%}
    {%- unless page_title contains shop.name %} &ndash; {{ shop.name }}{% endunless -%}
  </title>

  {% if page_description %}
    <meta name="description" content="{{ page_description | escape }}">
  {% endif %}

  <link rel="canonical" href="{{ canonical_url }}">

  {{ content_for_header }}

  {{ 'theme.css' | asset_url | stylesheet_tag }}
  {{ 'theme.js' | asset_url | script_tag: defer: true }}

  <script>document.documentElement.className = document.documentElement.className.replace('no-js', 'js');</script>
</head>
<body class="template-{{ template.name }}{% if template.suffix %} template-{{ template.name }}-{{ template.suffix }}{% endif %}">
  <a class="skip-link" href="#MainContent">Skip to content</a>

  {% sections 'header-group' %}

  <main id="MainContent" role="main" tabindex="-1">
    {{ content_for_layout }}
  </main>

  {% sections 'footer-group' %}
</body>
</html>
  • request.locale.iso_code — BCP 47 language for <html lang>
  • template.name — body class hook (product, collection, index)
  • canonical_url — SEO canonical link Shopify computes per page
  • page_title / page_description — set in templates or sections
  • {% sections 'header-group' %} — section groups from settings_data.json
Note: Never remove {{ content_for_header }}. Apps and Shopify features (Shop Pay, analytics) depend on it. Theme Check fails themes without it.