Shopify
Shopify app blocks for reviews and scripts
Shopify app blocks are how reviews, loyalty and related widgets should land on a Horizon storefront. Script tags that inject a star rating into product.liquid still exist in the wild. They fight the theme editor, they fight Core Web Vitals, and they break when the section markup changes. I am Alan Vo. I ship Shopify catalogues from the Gold Coast, including interiors and food brands where reviews and campaign scripts are not optional. In 2026 the supported storefront surface is a theme app extension: app blocks, app embeds, and app pixels, not a leftover <script> in theme.liquid.
Shopify documents this under theme app extensions and app blocks. This note is the production version: how I move a live store off script tags without losing ratings in Google, and without letting a review app become the LCP element.
Why Shopify app blocks replaced script tags on the storefront
Shopify app blocks replaced script tags because Online Store 2.0 already asked apps to be editor-first, and Horizon made that non-negotiable. A script tag writes DOM where the app guesses the product form lives. A theme block writes DOM where the merchant placed it. When Dawn became a forest of custom sections, the guess failed. When Horizon nested theme blocks and web components, the guess failed harder.
App blocks are Liquid + schema shipped inside the app, rendered inside a section that opts into @app. The merchant can move reviews below the fold, hide them on a gift-card template, or add them to a featured product on the homepage without asking the app vendor to support a new snippet name.
App embeds are the global sibling: a wrapper the merchant toggles once (often in theme settings under App embeds) for things that must exist on every page, such as a loyalty launcher. They are still a theme app extension, not a script tag with display:none in the header.
Script tags remain a compatibility hole. Some older apps still register them. Shopify has been tightening checkout and customer events. Storefront script tags are next in spirit even if a given app still "works." I treat every script tag on a Horizon build as technical debt with a conversion cost.
This is separate from checkout. Pixels on thank-you belong in web pixels and checkout extensibility, not in an app block. Storefront reviews belong here. If you are still mixing GTM, chat and review loaders in theme.liquid, read defer third-party tags without losing data after this. The theme-block model that hosts app blocks is Shopify theme blocks vs section blocks.
How Shopify app blocks work in the editor and in Liquid
How Shopify app blocks work is: the theme must accept them, the app must provide them, and the merchant must place them. All three fail independently.
A section accepts app blocks by including @app in its block types (Horizon sections that only accept @theme will not show the app in the block picker). JSON templates can also include app block instances. If you clone a Horizon product template and strip block types to "keep it clean," you have banned reviews.
The app provides a theme app extension with one or more blocks: star rating, review list, Q&A, badge. Each block has settings the merchant sees in the editor. Good apps expose "which product" (usually the current product) and load strategy. Bad apps still fetch a 400kb widget on first paint.
Liquid in the theme does not loop app blocks by vendor name. content_for (or the section's block renderer) prints whatever is in the tree. Developers who {% render 'okendo-reviews' %} inside a custom section have re-created the snippet problem. Delete that render when the app block exists.
App embeds inject a global snippet when enabled. I use embeds for launchers and for CSS the app needs everywhere. I do not use an embed to print a full review list on every URL. That is how collection pages download a review runtime they never show.
Deep JSON in settings_data.json will store app block IDs. Theme copy between stores does not always copy app blocks cleanly if the app is not installed. Duplicate a theme on the same shop, not as a ZIP you upload to a shop that lacks the app.
How I move reviews and loyalty onto Shopify app blocks
I move reviews and loyalty onto Shopify app blocks as a staged theme change, not as an app reinstall. Reinstalling is how you lose review data or your widget ID. The reviews live in the app. The theme only hosts them.
First I find every injection: theme.liquid, product.json, snippets named reviews, loox, yotpo, okendo, judge, stamped, plus any asset JS that writes a #reviews node. I screenshot PDP desktop and mobile with the current widget visible. That screenshot is the acceptance test.
Second I enable the app's theme app extension and app embed if the vendor still has both. Some apps leave the old script tag on "for compatibility." I turn the script tag off on the unpublished theme only, then confirm the app block still renders.
Third I place the rating summary near the title (static commercial spine) and the review list below the fold or in a tab-like group. Jewellery and food photography should not wait on a review iframe. The summary can stay high if it is lightweight. The list can lazy-load.
Fourth I set the product template presets so new products inherit the blocks. Horizon merchants create templates. If only product.json has the app block, the product.preorder.json template will ship naked.
Fifth I check collection cards. Star ratings on every card can be an app block in a card group, or a metafield the theme prints. An app block per card that boots a widget 48 times is an INP incident. Prefer a cached rating snippet or a metafield. Use the full widget on the PDP.
Sixth I move non-review scripts. Loyalty launchers: app embed, deferred. Size charts: app block on PDP. Wishlist hearts: often an embed plus a PDP block. Chat: not an app block, and not on checkout. Heatmaps: deferred, never on checkout.
Seventh I validate rich results. If the app outputs Product + Review JSON-LD, I test with Google's rich results tool and make sure the theme is not also printing a second Product schema with no reviews. Two Product graphs is how stars vanish from SERPs.
Production checklist
- Inventory script tags in Online Store, apps, and
theme.liquid. - Confirm the review and loyalty apps offer a theme app extension in 2026. If not, replace the app before you replace the theme.
- Unpublished theme: enable app embed, add app blocks to product (and any alternate product templates).
- Remove
{% render %}review snippets and hard-coded app includes from custom sections. - Disable the app's legacy script tag on that theme once the block is visible.
- Keep rating summary light near the title. Lazy-load the review list.
- Do not put a full review widget in the collection card loop.
- Check JSON-LD: one Product graph, reviews present if you claim aggregateRating.
- Test markets and languages. App blocks that ignore locale show English on a French market.
- Test quick-add and variant change. Some widgets cache the first product handle.
- Defer chat, loyalty popups and heatmap loaders until interaction. See the third-party tag note linked above.
- Re-run Lighthouse and field INP on PDP. Review apps are a frequent main-thread cost.
- Give the merchant an editor tour: where to hide reviews on gift cards and sample SKUs.
- After publish, confirm Search Console product snippets still show ratings if they did before.
What breaks when apps stay on script tags
The editor lies. The merchant moves a Horizon group and the review widget stays glued to a Dawn-era #shopify-section-product hook that no longer exists. Support tickets say "reviews disappeared after the redesign." They are in the DOM on another template, or in a display:none node the old script still targets.
Core Web Vitals regress. Script tags in theme.liquid run on every URL, including password, blog and policy pages. Collection INP dies when 48 cards each initialise a ratings framework.
SEO splits. The app prints review schema. The theme prints Product schema. Google picks one and drops stars. I keep a single graph, usually the app's if it is complete, or the theme's if the app only draws UI.
Checkout and cart drawers glitch when a script tag binds to form[action='/cart/add'] and Horizon's cart is a component. Add-to-cart succeeds, the drawer does not open, or it opens twice.
App blocks without @app on the section look like an app outage. The merchant reinstalls. You now have script tags and app blocks. Ratings duplicate.
Loyalty embeds that fire before consent paint a popup on first load in markets where you promised a CMP. That is a legal and INP problem. Gate the embed behind the same consent you use for ads pixels.
How I measure app-block migrations
I measure visible ratings, schema validity, and PDP INP. Visible: screenshot diff on the top 20 SKUs by revenue, not on the demo product. Schema: rich results test on a SKU that has reviews and a SKU that has zero. INP: field data on product URL group, plus a lab profile with the review list scrolled into view.
I also watch add-to-cart. A review app that hijacks the product form to "ask for a review after purchase" on the PDP is the wrong surface. After-purchase belongs post-checkout.
If organic landing pages lose review stars in the SERP within two crawl cycles, I assume duplicate or missing JSON-LD before I assume a ranking algorithm story.
Related work on this site
Catalogue-heavy Shopify work is where app blocks either stay quiet or wreck the photography. The Ferm Living interiors webshop has to merchandise rooms without a widget fighting the grid. The Partake Foods custom storefront has to carry a pack redesign, filters and a PDP that still adds to cart. Reviews and loyalty go in the editor on those kinds of builds. They do not go in theme.liquid.
FAQ
Do I need Shopify app blocks if my review app still works with a script tag?
Yes if you are on Horizon or you want merchants to move the widget. A script tag that still paints stars is not the same as a supported integration. Shopify app blocks survive section refactors. Script tags do not.
Are Shopify app blocks the same as theme blocks?
No. Theme blocks are your theme's files. Shopify app blocks are the app's theme app extension, placed into a section that allows @app. You often nest an app block next to theme blocks on the PDP. You should not fork the app's Liquid into your theme.
Can Shopify app blocks load on collection pages?
They can, and they often should not in bulk. A rating count on a card is fine if it is cheap. A full Shopify app blocks review list on every card is how you fail INP. Keep heavy widgets on the PDP.
Where should tracking scripts go if not in an app block?
Purchase and ads pixels belong in customer events, web pixels and GTM, not in a storefront app block. App blocks are UI on Online Store pages. Using them as a GTM injection point puts Tag Manager on every blog post and usually duplicates checkout tags.
Keep reading
Contact if you want this kind of work on a live store.