I’ve been treating Liquid partials as a small experiment: can a Liquid theme feel like an SPA without going headless?
Short answer: closer than I expected.
Longer answer: the fun part works; the platform glue still needs shopify engineering
The experiment
I forked Horizon 4.1.3 and wired up the partial-rendering runtime so the header, footer, and cart chrome stay in the DOM. Only a page-content region swaps when buyers navigate - collection to product, header links, that kind of browse flow. History API, prefetch on hover, View Transitions, the usual polish.
It maps cleanly onto how people already think about SPAs:
Persistent shell - nav, cart, drawer state survive route changes
Server-rendered HTML - Liquid stays the source of truth; no parallel GraphQL UI layer
Named regions - fetch and replace what changed, not the whole document
In my benchmarks, collection to product went from about 1.2 seconds (full reload) to about 49 ms (partial swap).
Live demo (password: ocontis):
The header does not blink when you click a product card.
Standard storefront events shopify:page:view, etc. work after each swap. Web pixel customer events page_viewed, etc. do not - WPM init is once-per-document, and the only fix I found was a theme-side intercept before content_for_header. It works; it should not live in theme code.
I think partials are a good fit for SPA-like architecture inside the Online Store stack and there might be a nice opportunity there. Shopify stepping in on pixel lifecycle (and maybe shell UX patterns) would keep it from feeling hacky.
Try it on github.
Full technical and performance breakdown on my blog
Curious if anyone else is experimenting with partials for in-store navigation.