Checkout UI extensions vs legacy Shopify checkout apps
How Shopify checkout UI extensions differ from script-tag and checkout.liquid apps, what each plan can use, and how to move your upsells without losing revenue.
For years, Shopify checkout customization meant one of two things: editing checkout.liquid (if you were on Plus) or letting an app inject a script tag into the thank you page. Post-purchase upsells, tracking pixels, surveys and trust badges all rode on that model.
Both paths are now closed. Shopify turned off checkout.liquid for the information, shipping and payment pages on August 13, 2024, and retired checkout.liquid, script tags and “additional scripts” on the thank you and order status pages on August 28, 2025. The replacement is Checkout Extensibility: checkout UI extensions, post-purchase extensions, Shopify Functions and web pixels, all running inside a sandbox Shopify controls.
If an app on your store still depends on the old model, it is either already broken or working around the rules. This guide explains what actually changed, what each Shopify plan can use, and how to evaluate an upsell app built on the new architecture.
Do you need Shopify Plus for checkout extensions?
Not for the parts most merchants care about. The plan requirement depends on where in the checkout an extension renders:
| Surface | Basic, Shopify, Advanced | Shopify Plus |
|---|---|---|
| Post-purchase page (one-click offer after payment) | Yes | Yes |
| Thank you page and order status page blocks | Yes | Yes |
| Information, shipping and payment pages (checkout UI extensions in the checkout itself) | No | Yes |
| Checkout Branding API (deep styling control) | No | Yes |
| Delivery and payment customization Functions | No | Yes |
| Basic checkout styling in the checkout editor (logo, colors, fonts) | Yes | Yes |
So a post purchase upsell shown between payment and the thank you page, and offers on the order confirmation page, are available to every store. Adding blocks to the payment step or rewriting shipping logic still requires Plus.
That matters for the build-vs-buy question. If your goal is a higher average order value rather than a bespoke checkout flow, you do not need Plus. You need an app that uses the post-purchase and order status extension points correctly.
What legacy checkout apps actually did
Understanding the old mechanics explains why Shopify shut them down.
Script tags. An app registered a JavaScript URL with Shopify, and Shopify loaded it on the storefront and (until 2025) the order status page. That script ran on the browser’s main thread with full access to the page. It could rewrite the DOM, read form fields, and call the app’s servers. It could also block rendering, conflict with other scripts, or fail silently when a browser extension blocked the request.
checkout.liquid. Plus merchants could edit the checkout template directly. That gave complete control, and complete fragility: Shopify could not ship checkout updates without risking a broken template, and every developer who touched it had to re-test the entire flow.
iframes and redirects. Some post-purchase apps redirected the customer to an app-hosted page after payment, or embedded an iframe. This meant a second page load at the most sensitive moment of the sale, a payment re-entry in the worst cases, and an experience that looked nothing like the store’s checkout.
The consequences for merchants were concrete:
- Speed. Every injected script is more main-thread work at the exact moment the shopper decides whether to finish. This is what Google’s Interaction to Next Paint metric measures; see how to keep checkout INP under 200 ms.
- Blocked offers. Ad blockers and privacy browsers routinely block third-party scripts. Offers injected by script simply did not render for a share of shoppers, and the analytics could not tell you how many.
- Security and compliance. Arbitrary third-party code near payment fields is a liability Shopify no longer accepts.
- Breakage on platform updates. Every Shopify checkout release was a risk for stores with custom templates.
How checkout UI extensions work
A checkout UI extension is a small bundle of JavaScript that Shopify runs in a web worker, isolated from the page. It cannot touch the checkout DOM. Instead it describes UI using Shopify’s component library (text, buttons, banners, product thumbnails, and so on), and Shopify renders those components natively in the checkout, matching the store’s checkout styling.
Key properties of this model:
- Extensions render only at named targets. Shopify defines where blocks can appear (for example after the order summary, on the order status page, or on the dedicated post-purchase page). An app cannot place something Shopify has not allowed.
- Data access is scoped. An extension reads cart and order data through Shopify’s APIs, and only the data the merchant approved when installing the app.
- Shopify serves the code. Extension bundles load from Shopify’s CDN as part of the checkout itself, so they are not subject to the third-party script blocking that killed legacy offers.
- Upgrade-safe. Shopify can update checkout without breaking extensions, because extensions never depended on checkout markup.
- Merchant-controlled placement. Extensions are added and positioned in the checkout editor (Settings > Checkout > Customize), not by pasting code.
The post-purchase surface has its own rules. A post-purchase extension renders after payment is authorized and before the thank you page. Accepting an offer adds the item to the existing order and charges the payment method already on file, which is why it is a true one-click upsell. Shopify requires that the offer states the customer will be charged, that a clear decline option is always available, and that no misleading urgency is used. Offers are also not shown for every order; some payment methods and order types are ineligible, and Shopify’s documentation lists the current exclusions.
Side by side
| Legacy apps (script tags, checkout.liquid, redirects) | Checkout UI extensions | |
|---|---|---|
| Where code runs | Browser main thread, on the checkout page | Isolated web worker; Shopify renders the UI |
| Access to checkout page | Full DOM access | None; components and scoped APIs only |
| Blocked by ad blockers | Frequently | Rarely; served by Shopify with the checkout |
| Breaks on Shopify updates | Often | No |
| Setup | Code snippets, developer time | Checkout editor, no code |
| Plans | checkout.liquid was Plus only | Post-purchase and order status page: all plans |
| Status in 2026 | Retired | Supported |
Three extensions worth running
1. One-click post purchase upsell. The customer has paid, trust is at its peak, and their payment method is stored. A relevant offer here (a refill, an accessory, a second unit at a discount) adds to the order without a second checkout. Cart X supports up to three upsells and three downsells in sequence, so a declined offer can fall back to a cheaper or different one. Read the pros and cons of post-purchase upsells before you design the sequence.
Example offer copy that stays inside Shopify’s rules:
Add a second pack of refills to this order for $18.00
$24.00. Your card on file will be charged $18.00. [Pay now] [Decline offer]
2. Order status page offers. The thank you page and order status page are visited repeatedly while a shopper waits for delivery. A discounted next-order offer or a complementary product block here is low-pressure and does not touch the checkout flow at all. Cart X’s drag-and-drop builder places these blocks; see how to optimize a Shopify thank you page.
3. Trust and delivery reassurance blocks (Plus). Plus stores can add native blocks on the shipping and payment steps: a returns guarantee, delivery timing, or review snippets exactly where hesitation happens. These are not upsells, but they protect the sale the upsell depends on.
Migrating your upsells
The short version: open Settings > Checkout > Customize and note which installed apps appear as app blocks or as the post-purchase app. Anything checkout-related that is missing there is not on the supported surfaces and should be replaced, not patched. Move tracking from “additional scripts” to web pixels in Settings > Customer events, then test with a real order. The full checkout.liquid upgrade guide walks through each step.
Frequently asked questions
Do checkout UI extensions replace checkout.liquid completely?
Yes. checkout.liquid no longer renders on any checkout page, and script tags and additional scripts no longer run on the thank you or order status pages. Checkout UI extensions, post-purchase extensions, Shopify Functions and web pixels are the supported replacements.
Can I run post-purchase upsells without Shopify Plus?
Yes. Post-purchase extensions and thank you / order status page extensions are available on Basic, Shopify and Advanced plans. Only customization of the information, shipping and payment steps is Plus-only.
Are extensions faster than legacy apps?
Extension code runs off the main thread and renders through Shopify’s own components, so it does not compete with the shopper’s taps the way injected scripts did.
Can ad blockers hide checkout UI extensions?
Extensions are served by Shopify as part of the checkout, so they are not caught by the third-party script blocking that hid legacy offers.
Try it on your store
Cart X is built on Checkout Extensibility: post-purchase offers run as a post-purchase extension, order status page offers as checkout UI extensions, and the in-cart popup as a theme app extension. Install it from the Shopify App Store; the free plan covers every feature up to 100 orders a month, and paid plans start at $19 with no revenue cap or commission.