Di 21 Gambaran Arsitektur Theme kita lihat enam lapisan theme. Sekarang kita mulai dari yang paling luar: layout, kerangka HTML yang ngebungkus semua halaman.
Layout itu dasar theme, tempat semua template dirender. Bayangin layout sebagai bingkai foto: bingkainya sama terus, yang ganti-ganti cuma fotonya (template). Header, footer, <head> dengan meta tag dan CSS, itu semua bingkainya.
Layout itu file Liquid yang bikin kamu bisa naruh konten yang diulang di banyak jenis halaman dalam satu tempat. Kalau gak ada layout, tiap template harus nulis ulang header dan footer sendiri-sendiri, dan tiap ganti logo harus edit 15 file.
Lokasi
Di folder layout/:
└── theme
├── layout
| ├── theme.liquid
| ...
├── templates
...Dua Jenis Layout
- General, buat semua halaman non-checkout. File bawaannya
theme.liquid, yang wajib ada di semua theme. Ini yang kita bahas di bab ini. - Checkout, buat halaman checkout, cuma buat merchant Shopify Plus lewat
checkout.liquid. Tapi ini udah dihentikan: gak didukung buat langkah Information, Shipping, dan Payment, dan dihentikan buat halaman Thank you dan Order status sejak 28 Agustus 2025 (toko non-Plus sampai 26 Agustus 2026). Toko yang masih pakai harus pindah ke Checkout Extensions. Bahasannya di 34 checkout.liquid (deprecated).
Struktur Dasar
Karena layout itu dasar theme, isinya harus ngikutin struktur dokumen HTML standar, dan hampir selalu berisi dua object Liquid:
<!DOCTYPE html>
<html>
<head>
...
{{ content_for_header }}
...
</head>
<body>
...
{{ content_for_layout }}
...
</body>
</html>Dua object ini wajib ada di theme.liquid. Kalau salah satunya gak ada, kamu gak bisa nyimpen atau nge-update file-nya, baik lewat code editor maupun Shopify CLI. Jadi ini bukan saran, ini syarat.
1. content_for_header
Wajib di dalam <head>. Object ini ngeluarin semua skrip yang dibutuhin Shopify secara dinamis: hCaptcha, skrip app, analitik, skrip theme editor, dan lainnya.
Aturannya, udah dibahas di 13 Objects Global > 1. content_for_header: jangan pernah dimodifikasi atau di-parse. Isinya bisa berubah kapan aja, dan kalau kamu ngandelin isinya, kodemu bakal rusak tanpa peringatan.
2. content_for_layout
Wajib di antara <body> dan </body>. Object ini ngeluarin isi template yang lagi dirender. Ini titik di mana halaman produk, halaman koleksi, atau halaman apapun “disuntikkan” ke dalam bingkai.
❌ salah, content_for_layout di luar body, dan content_for_header hilang
<!DOCTYPE html>
<html>
<head>
<title>{{ page_title }}</title>
</head>
<body>
{% sections 'header-group' %}
</body>
</html>
{{ content_for_layout }}✅ benar
<!DOCTYPE html>
<html>
<head>
<title>{{ page_title }}</title>
{{ content_for_header }}
</head>
<body>
{% sections 'header-group' %}
{{ content_for_layout }}
{% sections 'footer-group' %}
</body>
</html>Isi Layout
Layout itu file .liquid, jadi isinya HTML dan Liquid biasa. Dia bisa akses semua object global dari 13 Objects Global, plus dua object di atas. Yang biasanya ditaruh di layout:
- Meta tag dan SEO di
<head>:<title>, meta description, Open Graph, canonical. Bahasannya di 48 SEO Metadata, hreflang, robots.txt. - CSS dan font yang dipakai semua halaman.
- Section group header dan footer lewat tag
sections. - Skrip global yang dibutuhin di semua halaman.
Ini contoh theme.liquid yang realistis, ngerangkai hal-hal yang udah kita pelajari:
<!doctype html>
<html lang="{{ request.locale.iso_code }}" dir="{{ request.locale.direction }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="canonical" href="{{ canonical_url }}">
{%- if settings.favicon != blank -%}
<link rel="icon" type="image/png" href="{{ settings.favicon | image_url: width: 32, height: 32 }}">
{%- endif -%}
<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 %}
{% render 'meta-tags' %}
{% style %}
{{ settings.type_body_font | font_face: font_display: 'swap' }}
{{ settings.type_header_font | font_face: font_display: 'swap' }}
:root {
--font-body-family: {{ settings.type_body_font.family }}, {{ settings.type_body_font.fallback_families }};
--font-heading-family: {{ settings.type_header_font.family }}, {{ settings.type_header_font.fallback_families }};
--color-background: {{ settings.colors_background }};
--color-text: {{ settings.colors_text }};
}
{% endstyle %}
{{ 'base.css' | asset_url | stylesheet_tag }}
{{ content_for_header }}
</head>
<body class="template-{{ template.name }}{% if template.suffix %} template-{{ template.name }}-{{ template.suffix }}{% endif %}">
<a class="skip-to-content-link" href="#MainContent">
{{ 'accessibility.skip_to_text' | t }}
</a>
{% sections 'header-group' %}
<main id="MainContent" role="main">
{{ content_for_layout }}
</main>
{% sections 'footer-group' %}
<script src="{{ 'global.js' | asset_url }}" defer="defer"></script>
</body>
</html>Bedah bagian-bagian pentingnya:
langdandirdarirequest.locale, biar bahasa kanan-ke-kiri kaya Arab tampil benar. Dari 13 Objects Global > 3. shop_locale.canonical_urlbuat SEO.<title>yang dirakit daripage_title,current_tags,current_page, danshop.name, semuanya object global.font_facedenganfont_display: 'swap'dan CSS variable buat font dan warna, sesuai pola dari 06 Theme Editor dan Code Editor > 1. Pengaturan Warna biar live preview jalan.stylesheet_tagbuat CSS utama.- Class
<body>daritemplate.namedantemplate.suffix, dibahas di bawah. - Skip link buat aksesibilitas, teksnya lewat
t. Bahasannya di 55 Accessibility. sections 'header-group'dansections 'footer-group', section group yang bisa diatur merchant.<main>denganid="MainContent"yang ngebungkuscontent_for_layout.- Skrip dengan
deferbiar gak ngeblok render.
CSS Selector per Template
Trik yang dipakai hampir semua theme: keluarin data dari object template sebagai class di <body>, biar kamu bisa bikin aturan CSS yang cuma berlaku di jenis halaman tertentu:
<body class="template-{{ template.name }}">
...
</body>Terus di CSS:
.template-product {
margin-bottom: 2em;
}Halaman produk dapat template-product, halaman koleksi dapat template-collection, dan seterusnya. Nilai-nilai template.name ada di 13 Objects Global > template. Dengan nambahin template.suffix kaya di contoh di atas, alternate template product.pre-order.json dapat class tambahan template-product-pre-order.
Layout Alternatif
Kamu bisa bikin lebih dari satu layout. Misalnya layout/full-width.liquid tanpa header dan footer buat landing page kampanye, atau layout/minimal.liquid buat halaman gift card yang mau dicetak.
Cara nentuin layout mana yang dipakai itu di level template, dan caranya beda tergantung jenis template:
- Template JSON: pakai atribut
layoutdi file JSON-nya. Bahasannya di 23 Templates. - Template Liquid: pakai tag
layoutdari 12 Tags Khusus Theme > layout.
Template JSON:
{
"layout": "full-width",
"sections": { ... },
"order": [ ... ]
}Template Liquid:
{% layout 'full-width' %}Dan dua-duanya bisa gak pakai layout sama sekali: "layout": false di JSON, atau {% layout none %} di Liquid. Hasilnya cuma isi template-nya doang, tanpa <html>, <head>, apapun. Ini yang dipakai template gift_card.liquid yang punya struktur HTML sendiri.
Kalau atribut atau tag-nya gak disebut, theme.liquid yang dipakai.
❌ salah, layout alternatif tapi lupa content_for_layout, template-nya gak pernah muncul
{% comment %} layout/full-width.liquid {% endcomment %}
<!doctype html>
<html>
<head>{{ content_for_header }}</head>
<body>
<h1>Kampanye Besar</h1>
</body>
</html>✅ benar, layout alternatif tetap butuh dua object wajib
<!doctype html>
<html>
<head>{{ content_for_header }}</head>
<body>
{{ content_for_layout }}
</body>
</html>Catatan: cuma theme.liquid yang diblokir nyimpen kalau dua object-nya hilang. Layout alternatif bisa disimpan tanpa itu, tapi ya hasilnya halaman kosong atau fitur Shopify yang gak jalan. Jadi tetap taruh.
Ringkasan
- Layout itu bingkai yang ngebungkus semua template, tempat konten yang diulang di banyak halaman:
<head>, header, footer. theme.liquidwajib ada, dan wajib berisicontent_for_headerdi<head>dancontent_for_layoutdi<body>. Tanpa itu, file-nya gak bisa disimpan.content_for_headerjangan dimodifikasi, isinya skrip Shopify yang bisa berubah kapan aja.content_for_layoutitu titik suntik template ke dalam layout.- Layout bisa akses semua object global, dan biasanya berisi meta tag, font, CSS, section group header/footer, dan skrip global.
- Class
<body>daritemplate.name(dantemplate.suffix) buat CSS per jenis halaman. - Layout alternatif dipilih di level template: atribut
layoutdi JSON, taglayoutdi Liquid, ataufalse/nonebuat tanpa layout. checkout.liquidudah dihentikan, checkout dikustomisasi lewat Checkout Extensions.
Bab selanjutnya kita masuk ke lapisan berikutnya: template. Bedanya template JSON dan Liquid, struktur file JSON-nya, dan cara bikin beberapa template buat jenis halaman yang sama.