A WordPress Plugin Conflict Debugging Checklist We Actually Use
The standard forum advice — deactivate every plugin, then turn them back on one by one — is the slowest…
Checkout.liquid didn’t die in one shot. Shopify pulled it in two pieces: the Information, Shipping, and Payment pages stopped rendering checkout.liquid on August 13, 2024, and the Thank You and Order Status pages — along with any app still relying on script tags or “additional scripts” there — got the same treatment on August 28, 2025. A year on from the second date, we still get pulled into stores where the first migration was a rush job and the second one is the reason a tracking pixel quietly stopped firing months ago and nobody caught it until the numbers looked wrong. If either of those is you, here’s the actual boundary of what Checkout Extensibility lets you touch now — not the version in Shopify’s marketing copy.
Checkout.liquid let you edit the checkout page directly — HTML, CSS, inline script, all of it — but only if you were on Shopify Plus. Everyone else never had that access; the standard hosted checkout was always locked down to a logo and a couple of colors. Checkout Extensibility replaces that single editable template with three systems that barely overlap:
Add Web Pixels for anything that used to be a tracking script pasted into checkout.liquid, and that’s the whole surface. If what you need doesn’t fit one of these four buckets, it’s probably not happening — more on that below.
More than the “you’re stuck with whatever Shopify gives you” crowd thinks, less than the “it’s basically as flexible as before” crowd tells clients. Concretely:
Visual branding is genuinely deep: accent, canvas, critical, and decorative color roles set independently per section — header, main content, and order summary can each carry a different scheme — plus a font picker pulling from Shopify’s library of a hundred-plus hosted fonts. If none of those match the brand typeface, custom font upload is possible too, via the CheckoutBranding API’s checkoutBrandingUpsert mutation, though Shopify’s own docs warn it costs render performance since the font has to download before checkout text can paint. Button fill vs. outline, corner radius, logo placement. This covers the “make it look like the rest of the site” work that used to eat half of every checkout.liquid ticket, and it survives Shopify’s redesigns instead of breaking on them.
New UI, at fixed points. A checkout UI extension can add a banner, a checkbox, a text field, a collapsible block, an image — Shopify’s own component library, not arbitrary markup — and place it at one of the defined targets: after the header, after the cart line list, before the shipping options, before the Pay Now button, on the Thank You and Order Status pages. The general-purpose block target alone has fourteen placements a merchant can drop it into from the drag-and-drop Checkout Editor. A gift-note field, an age-verification checkbox, a delivery-instructions box, a small “this order supports X” banner — all normal, well-supported work. Here’s roughly what that looks like for a bulk-order notice we’d actually ship:
// shopify.extension.toml
api_version = "2025-10"
[[extensions]]
name = "bulk-order-note"
handle = "bulk-order-note"
type = "ui_extension"
[[extensions.targeting]]
target = "purchase.checkout.block.render"
module = "./src/BulkNote.jsx"
// src/BulkNote.jsx
import {
reactExtension,
Banner,
useCartLines,
} from "@shopify/ui-extensions-react/checkout";
export default reactExtension(
"purchase.checkout.block.render",
() => <BulkNote />
);
function BulkNote() {
const lines = useCartLines();
const bulk = lines.some((line) => line.quantity >= 12);
if (!bulk) return null;
return (
<Banner title="Bulk order" status="info">
Orders of 12+ units of one item ship palletized, 5-7 business days.
</Banner>
);
}
Business logic moved into Shopify Functions, and this is the one place where extensibility is actually more capable than checkout.liquid ever was, because it runs server-side and deterministically instead of a client-side script racing the page render. Hide a shipping rate when the cart is under a weight threshold. Reorder payment methods for wholesale accounts. Block checkout entirely when a retail customer has a wholesale-only SKU sitting in the cart. Apply a discount that depends on combinations checkout.liquid could never evaluate reliably. It’s more code than the old inline-script approach, and it’s also a lot less likely to quietly break at 2am because Shopify shipped a checkout update.
This is the part that gets glossed over, and the part that actually burned people. Some checkout.liquid behavior didn’t migrate to a new system — it just isn’t available anymore:
If your checkout.liquid did any of this, there’s no equivalent flag to flip. That work gets rebuilt a different way or it gets dropped, and pretending otherwise to a client just moves the bad news later into the project.
A lot of the migration content out there undersells how real this constraint is, because “don’t worry, extensibility covers everything” is an easier sentence to write than “some of what you had is gone for good.” We’d rather say the second one up front. Shopify traded raw flexibility for a checkout that can’t be broken by a merchant’s own script, that upgrades cleanly, and that Shopify can keep fast and PCI-compliant without auditing everyone’s custom Liquid. That’s a defensible trade. It just isn’t a free one, and treating it as free is how a fixed-bid checkout project goes underwater in week three.
We’ve also mostly stopped recommending the no-code “checkout customizer” apps that showed up once extensibility launched. Most of them are a thin admin UI wrapped around two or three of the same extension targets you can register yourself in an afternoon, for a recurring fee that outlasts the one-time dev cost within a year. If a client needs one field and one banner, we write the extension. If they need six apps’ worth of checkout behavior, that’s usually a sign to slow down and figure out how much of it actually needs to live in checkout at all, versus earlier in the funnel.
And if what a business genuinely needs is checkout behavior this system doesn’t expose — a custom split-payment flow across two processors is the one we hear most — we say so instead of stacking three Functions and a UI extension to fake it. That’s usually the point worth asking whether Shopify’s native checkout, specifically, is still the right fit for that one requirement. WooCommerce hands the checkout template back to you, at the cost of owning its security and upkeep yourself — a fair trade for a business whose checkout logic is genuinely unusual, and a bad one for a normal DTC store that just wants a checkout that stays up.
Don’t port line by line. Audit what checkout.liquid was actually doing and sort it into four piles: pure styling goes to branding tokens, added UI goes to a UI extension, business rules go to a Function, tracking goes to Web Pixels. Whatever’s left after that sort is the genuinely unsupported pile — decide which of it matters enough to solve a different way, and which of it was a workaround for a problem that doesn’t even exist anymore. Budget for a rebuild, not a migration, and you won’t be the one explaining to a client in week four why the timeline just doubled.
Tell us what you're building and we'll tell you honestly whether we're a fit.
The standard forum advice — deactivate every plugin, then turn them back on one by one — is the slowest…
Almost every brief grows the word "AI" somewhere in it, and hardly any of them say what that means. These…
Self-hosted n8n is easy to stand up and easy to neglect once it's quietly running a client's order pipeline. Here's…