Shopify Plus · 7 min read

Shopify’s New Partial Tag: You’ve Been Paying Apps To Do What Liquid Now Does Natively

Shopify's New Partial Tag You've Been Paying Apps To Do What Liquid Now Does Natively

Key Takeaways

  • Shopify’s July ’26 Liquid developer preview adds two tags, {% block %} and {% partial %}, letting a template compose a full page and refresh named regions of it without a client-side framework.
  • A partial is server-rendered HTML that JavaScript fetches and swaps into the page. The apply() helper carries over focus, scroll position, form values, and text selection on its own.
  • The workaround this replaces, pairing the Section Rendering API with a hand-built fetch-and-replace or a JS framework, is a real contributor to the extra 50 to 150KB of JavaScript a typical app install adds to a page.
  • Median Shopify store LCP sits at 4.2 seconds against a 2.5 second “good” threshold, and only 48% of stores pass Core Web Vitals on mobile, where over 60% of Shopify traffic happens.
  • This is a developer preview. Opt in on a development store, expect rough edges around the theme editor’s design mode, and hold off on shipping it to a live client store.
  • Sections, JSON templates, and content_for aren’t going anywhere. Block and partial sit alongside the architecture you already know. They don’t replace it.

You added an app to make your filter sidebar update without reloading the page. Or you paid a developer to wire a JS framework onto your product page so the price updates the second someone picks a different karat or gemstone.

You were right to want that. A full page reload on every filter click feels broken to a 2026 shopper, and they bounce over it.

Here’s the harder question: what did that instant update actually cost you?

More than you think.

Shopify just shipped a way to get the same feel, server-rendered HTML swapped into the page, without the framework or the app. It’s in developer preview as of July 21, 2026. If you’re starting a new theme build right now, it changes what you should reach for first.

Split-screen diagram showing the old Section Rendering API plus JS framework flow next to the new Liquid partial fetch and apply flow

The Workaround You Didn’t Know You Were Paying For

Before this preview, updating part of a page without a reload meant one thing: the Section Rendering API. You’d fetch a section’s HTML from the server, then write JavaScript, often a lot of it, to find the right spot in the DOM and swap the content in.

Most themes and apps skip the hard half of that by installing a client-side framework instead. React or Vue handles the swap, the state, the re-render. It works. It also ships every visitor a bundle of JavaScript just to move HTML from one place to another.

That bundle isn’t free. A new app install adds 50 to 150KB of JavaScript to every page load on average. For a store already sitting near the 2.3 to 2.5 second LCP threshold, one install can push it over the edge.

Multiply that by a filter app, a quick-view app, a wishlist app, and a size-guide app, and you’ve rebuilt a single-page app’s worth of JavaScript weight, one install at a time, to do something the browser and server could have handled together.

Two Tags, One Idea: Compose the Page in Liquid

The preview adds {% block %} and {% partial %}. They solve different problems, but they share one goal: let the Liquid template describe the whole page, not just a slice of it.

{% block %} calls a reusable theme block directly from a template. Instead of routing every block through the theme editor and a JSON template, you name the block file, pass it parameters, and give it body content, the same way you’d use {% render %} for a snippet. A product page might call a metal selector block and hand it the current product:

liquid

{% block 'metal-selector', block.settings.product: product, class: 'pdp-metal' %}
{% endblock %}

{% partial %} marks a region of that page as independently refreshable. Wrap the part that actually changes, not the whole page, and give it a name:

liquid

{% partial 'price-and-stock' %}
  {% render 'price-block', product: product, variant: current_variant %}
{% endpartial %}

When a shopper picks a different karat, a few lines of JavaScript call partials.fetch('price-and-stock', {url: newUrl}) and then partials.apply(update). The server renders the new price in Liquid, same as the first load. No client framework re-renders anything. No app has to inject its own script tag to do it.

That’s the whole shift. Composition and interactivity both stay in Liquid, readable top to bottom in the template, instead of split across a theme file, a JSON template, and a bundle of client-side JavaScript.

What the Browser Handles, and What’s Still Yours

apply() does more than swap HTML. Focus, text selection, form values, and scroll position all carry over the swap automatically, the housekeeping a full page load normally handles for you.

Everything else is still your job:

  • Stale responses. If a shopper clicks two filters fast, a slow first request can resolve after the second and overwrite it. Pass an AbortSignal so the latest request wins.
  • Loading feedback. Nothing tells the shopper a request is in flight unless you add it. Set aria-busy on the region while it updates.
  • Announcements. A silent DOM swap says nothing to a screen reader. Pair it with a live region for messages like “3 rings match your filters.”
  • Local UI state. An open accordion or expanded filter panel resets when its region gets replaced. Restore it after the update lands.

None of this is new work exactly. It’s the same accessibility discipline any AJAX interaction needs. What’s new is how little plumbing it takes to get there.

block vs content_for vs render: Pick the Right One

All three render reusable Liquid. Which one fits depends on who’s in charge of the page.

TagUse whenWho controls it
{% block %}The template decides the structure and passes data inYou, in code
{% content_for %}A merchant adds and arranges blocks in the theme editorThe merchant, in the editor
{% render %}Repeated internal Liquid with no editor settingsYou, for snippets

A theme built for client stores probably uses all three: content_for for sections a merchant drags around the homepage, block for structural pieces like a product card that always renders the same way, and render for pure logic snippets like a price formatter.

Where It’s Still Rough

This is a developer preview, not a shipped feature. A few things to know before you touch a client store with it:

  • You opt in per development store through feature previews. Production stores can’t turn this on yet.
  • The theme editor’s design mode doesn’t fully support partial regions. Developers testing it publicly have hit errors when a partial-driven page loads inside the customizer, because that code path predates partials.
  • Theme Check 3.28.0 adds new rules for Liquid-first themes, catching oversized files, schema mismatches, and complexity issues, a sign Shopify expects these patterns to get more common, not less.
  • Page history, titles, and analytics tracking on a partial-driven navigation are still your responsibility to wire up.

Build it behind a flag, test the customizer path specifically, and don’t put it in front of a client’s live traffic yet.

Why This Matters Now

Shopify’s own performance team reports that 79% of active stores now pass Core Web Vitals, and every shared component they optimize gets faster automatically across every store using it. That’s real progress. It also means the JavaScript your theme or your apps add is an increasingly large share of what’s left to fix.

The rest of the data makes the case sharper. CoreWebVitals.io, tracking real user data across roughly 925,000 mobile URLs, puts the median Shopify store LCP at 4.2 seconds, well past the 2.5 second “good” threshold. Only 48% of stores pass all three Core Web Vitals metrics on mobile, even though mobile drives over 60% of Shopify traffic. And the conversion math hasn’t changed: shave a second off load time and conversions rise by roughly 7%, according to widely cited Deloitte research.

Bar chart showing median Shopify store LCP at 4.2 seconds against the 2.5 second Core Web Vitals threshold

If you’re deciding right now how a new theme handles filtering, price updates, or cart interactions, that decision either adds to the JavaScript weight dragging down that 4.2 second median, or it doesn’t. Partials, even in preview, are worth prototyping for exactly that reason: the interactivity most themes bolt on with an app is the same category of weight hurting mobile Core Web Vitals scores today.

The preview will change before it’s stable. The problem it’s solving won’t.

Is Shopify’s partial tag ready for production stores?

No. It’s a developer preview as of July 2026, available only on development stores through feature previews. Existing production themes are unaffected and keep working exactly as before.

Does {% partial %} replace the Section Rendering API?

For the specific job of refreshing a named region without a reload, yes, that’s the intent. The Section Rendering API still exists and still works for other use cases, but partials give you the fetch-and-swap pattern natively instead of hand-building it.

Do I need to migrate my whole theme to use blocks and partials?

No. Sections, JSON templates, and content_for keep working unchanged. Block and partial are an additional way to compose specific pages or regions, not a rewrite requirement.

Is this related to Hydrogen or headless Shopify?

No, they solve different problems. Hydrogen is a React framework for fully custom, headless storefronts. Blocks and partials keep you inside standard Liquid themes and add framework-like interactivity without leaving that architecture.

The Real Point

You didn’t need a framework to make a price update without a reload. You needed the browser and the server to do the one thing they’re both already good at: render HTML and swap it in. Shopify’s partial and block tags just made that the native path instead of the workaround.

Stop reaching for an app or a framework to fake instant updates. Start asking whether the region you want to refresh is small enough to name and wrap in a {% partial %}.

If you’re building a new theme from the Skeleton base right now, test blocks and partials on a dev store before you hard-code the old fetch-and-stitch pattern into sections you’ll be maintaining for years.

Reader response

Was this useful?

One tap. No account, no email.

Javaid Ahmad
About the author

Javaid Ahmad — Fullstack ecommerce engineer

6+ years shipping Shopify Plus, WordPress and Magento systems for US/UK retailers — including high-AOV jewelry brands. Lead of ecommerce engineering at Apzee Solutions. Open to Dubai & Saudi roles.

Leave a comment

Not published.

Comments are reviewed before they appear, so yours will not show up straight away. Your email is never published.