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 %} – tagged "{{ current_tags | join: ', ' }}"{% endif -%}
{%- if current_page != 1 %} – Page {{ current_page }}{% endif -%}
{%- unless page_title contains shop.name %} – {{ 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.