App Blocks vs. Liquid Sections in Shopify
App block or Liquid section? A side-by-side of how each renders, what a theme update does to each, when to pick which, and the honest trade-off of both.
What a Shopify theme app extension is, how app blocks render into a theme, why they survive theme updates, and the theme permission apps need.
A theme app extension is how a Shopify app adds sections, blocks, and scripts to a storefront without writing into the theme's own files. The app ships an extension; the theme references it through a stable set of slots; the merchant places the app's blocks in the theme editor exactly like native ones. The code never becomes part of the theme.
That single architectural fact — app code lives in the app, not the theme — is why
this topic matters far beyond "how apps integrate." It is the reason app blocks
survive theme updates that overwrite hand-pasted .liquid files, and it is the
model SectionGuard uses to render sections that a theme update or
swap can't touch.
This is the hub for the whole topic. It covers what an extension actually is, how
its blocks render, how it differs from a Liquid section you write into
sections/, the API that makes app sections work, and the theme permission an app
requests. Each section links down to a deeper guide for the specific question you
have.
Technically, a theme app extension is a folder in an app's codebase — historically
extensions/<name>/ in a Shopify CLI app — that contains blocks and
snippets written in Liquid, plus static assets and a locales folder. When
the app is deployed, Shopify hosts that extension. Themes built on Online Store
2.0 expose named slots where those blocks can appear, so the app's block shows up
in the theme editor's "Add block" or "Add section" menu next to the theme's own.
There are two shapes of block:
{ "type": "@app" } in its blocks array). A reviews widget, a
size-chart block, or an upsell added into the product template is an app block.<script> tags in
<head>.Both render through the same extension, and both are configured by the merchant in the theme editor without touching code. What they never do is modify the theme's files.
The mechanism is worth understanding because it explains the durability. A 2.0 theme's JSON templates and sections declare where app blocks are allowed. When the storefront renders, Shopify looks up which app blocks the merchant added to those slots, pulls the corresponding Liquid from the installed app's extension, and renders it inline — as if it were part of the page — while the source stays hosted with the app.
Because the block's Liquid, CSS, and JavaScript are served from the extension and merely referenced by the theme, the theme file itself contains only a pointer, not your markup. That is the whole trick. For the deeper walkthrough of the API that resolves and returns section markup, see The Section Rendering API.
If you have written a section by hand, you already know the other model: a
.liquid file in the theme's sections/ folder with a {% schema %} block. It is
the most flexible route and the one most tutorials teach — covered step by step in
How to create a custom section.
The difference isn't capability; both can produce the same on-screen result. The difference is ownership and lifecycle:
Neither is "correct" in the abstract — a one-off tweak is fine hand-coded; a section you rely on long-term is safer app-rendered. The full trade-off, including the honest downside (an app block disappears if the app is uninstalled), is in App blocks vs. Liquid sections.
App sections and dynamic section updates rely on the Section Rendering API — the endpoint that returns the rendered HTML of a specific section on its own, so a page can refresh one section (a cart drawer, a filtered product grid, a swatch change) without a full reload. Understanding it clarifies both how app-rendered sections are delivered and how to build fast, partial UI updates in a theme.
The request shape, the sections and section_id parameters, and worked
JavaScript examples are in
The Section Rendering API.
An app that ships a theme app extension needs a way to interact with the merchant's
theme. That's where the write_themes access scope comes in. It's the
permission an app requests to work with theme assets through the API — and it is a
reasonable thing to want to understand before you grant it.
The honest version: extensions are the non-destructive integration path (that's
the point of them), and the scope an app declares should match what it actually
does. What read_themes and write_themes each allow, why an extension-based app
requests them, and how to check an app's scopes before installing, are covered in
What is the write_themes scope?.
The cluster guides below each take one question further. Start with the one that matches what you're doing:
If your real question is "how do I keep my sections when the theme changes," read this pillar alongside Update your theme without losing customizations and the honest comparison of file-based vs. app-based sections — together they explain why extension-rendered sections survive updates that overwrite theme files, and where SectionGuard fits.
Step-by-step how-tos and explainers in this topic.
App block or Liquid section? A side-by-side of how each renders, what a theme update does to each, when to pick which, and the honest trade-off of both.
How the Shopify Section Rendering API returns a single section's HTML, the sections and section_id parameters, and worked fetch examples.
What the Shopify write_themes access scope grants, how it differs from read_themes, why extension apps request it, and how to check an app's scopes.
SectionGuard renders your custom sections through a Theme App Extension — your theme stays clean and fully updatable.
Free for up to 3 sections · No credit card · Works on OS 2.0 & Horizon.