What Varnish FPC and Hyva already solve before a build pipeline is needed
Static Site Generation, Incremental Static Regeneration and prerendering services promise fast, cache-friendly store pages, but they bring their own build pipeline with artifact stores, rebuild windows and separate cache invalidation. This article shows precisely, in technical terms, where Magento with Hyva, Varnish Full Page Cache and ESI-backed dynamic islands already deliver the same benefits without that added complexity, and when a hybrid approach is still justified.
Table of Contents
- 1. Framing: Why the prerendering trend reaches store teams too
- 2. SSG, ISR and prerendering: the technical basics
- 3. The build pipeline complexity SSG stacks bring along
- 4. What Magento already delivers with Hyva and Varnish FPC
- 5. ESI and Alpine.js: dynamic islands inside cached pages
- 6. Cache invalidation: tags instead of rebuild windows
- 7. Prerendering services for crawlers: the pattern and its limits
- 8. When a headless or hybrid approach is still justified
- 9. Decision framework: weighing cost against benefit
- 10. Summary
- 11. FAQ
1. Framing: Why the prerendering trend reaches store teams too
The JAMstack world has been making a particular promise for years: if a page is delivered as fully pre-built HTML from a CDN, it is faster, cheaper and more robust than any page rendered from a backend on every request. Next.js, Gatsby and Astro have perfected this pattern for content sites, and agencies increasingly carry it into Magento and Hyva store projects too, often without first checking whether the underlying problem is even unsolved there.
For a team running a Magento shop with a Hyva theme, the right question is therefore not "should we adopt SSG" but "which specific technical problem are we trying to solve". Is it time to first byte, the compute cost of repeated rendering, the indexability of content for crawlers, or consistent delivery of personalized data such as prices and stock levels? Each of these questions already has a different, often already-solved answer in a server-rendered Magento stack.
This article classifies prerendering, SSG and ISR cleanly on technical grounds, shows concretely what Varnish Full Page Cache and Hyva's ESI/Alpine.js islands already cover, and honestly names the narrow scenarios where an additional build pipeline is still worthwhile. It focuses exclusively on rendering mechanics, caching correctness and operational effort, not on search engine ranking factors.
2. SSG, ISR and prerendering: the technical basics
Static Site Generation (SSG) means a build step compiles templates and content data into finished HTML files long before any request arrives. These files land in an artifact store and are distributed from there to a CDN. At runtime there is no server rendering left, every request hits a static file at the edge directly. The upside is extremely low latency and practically zero compute load per request.
Incremental Static Regeneration (ISR), coined by Next.js, mitigates the biggest problem of pure SSG: with thousands of product pages, a full rebuild on every content change would be too slow. ISR instead allows individual pages to be regenerated after a time window (revalidate) or via webhook, while the previous version keeps being served in a stale-while-revalidate fashion until then. That is a compromise between freshness and build effort, not a substitute for real-time consistency.
Prerendering services such as Prerender.io or Rendertron solve a third, related problem: with client-side rendered single-page applications (SPA), crawlers and bots often only see an empty HTML shell because the actual content only materializes via JavaScript in the browser. These services render the page server-side in a headless browser ahead of time and serve the result specifically to bots. For Hyva this is structurally irrelevant, since Magento already delivers finished HTML server-side, but the pattern is worth studying as a contrast.
3. The build pipeline complexity SSG stacks bring along
A real headless SSG stack does not consist of just the frontend framework. It needs a build server that is triggered on every content change, a webhook listener that receives changes from the CMS or PIM, a versioned artifact store for the generated HTML files, and a CDN invalidation step that updates all affected edge nodes after every deploy. For a catalog with several thousand SKUs, a full rebuild can take several minutes to tens of minutes, which forces incremental builds with dependency graphs: which pages depend on which changed record, and how is that determined reliably.
On top of that come operational edge cases that simply do not exist in a classic PHP request-response model: race conditions between two webhooks arriving concurrently, stuck builds that silently keep serving old content, and a staleness window in which visitors see different versions of the same page depending on which edge node they hit. The frontend, the backend API and the artifact store are also three separate deployment targets that need to be monitored and versioned together, instead of a single origin stack.
This complexity is not an accident, it is the price for the SSG promise of "no server rendering at request time". For pure marketing or blog content without personalization, that price often pays off. For a transactional store with prices, stock levels and per-user cart state, the calculation is far less clear-cut, as the following sections show.
4. What Magento already delivers with Hyva and Varnish FPC
Magento's Full Page Cache, typically via Varnish, stores fully rendered HTML responses per URL and context (customer group, currency, store view) in memory. A cache hit is served in single-digit milliseconds without PHP-FPM being contacted at all. The result is functionally identical to a pre-built static file, with one important difference in the mechanism: FPC lazily materializes the "static" page on the first request miss, instead of generating it upfront for every possible URL in a separate build step. There is no artifact store, no build server and no deploy pipeline for HTML snapshots.
Hyva amplifies this effect because it produces lean HTML server-side without a client hydration payload. There is no virtual DOM, no React or Vue runtime that first has to assemble the actual content in the browser. Once a page sits in FPC, its delivery is effectively equivalent to serving a static HTML file, just without the upfront build. For pages with predictably low change frequency, such as CMS pages or category landing pages, this effect can additionally be reproduced through sitemap-based cache warming, which achieves the same benefit as an SSG build "generate all pages upfront", just triggered lazily instead of eagerly.
# varnish.vcl - Magento Full Page Cache purge and ESI pass-through
sub vcl_recv {
# Let Magento-generated ESI fragments bypass the main object cache
if (req.url ~ "^/esi/") {
return (pass);
}
# Honor Magento's tag-based PURGE requests from the admin panel
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return (synth(405, "Not allowed"));
}
ban("obj.http.X-Magento-Tags ~ " + req.http.X-Magento-Tags-Pattern);
return (synth(200, "Purged"));
}
}
sub vcl_backend_response {
# Enable ESI processing only for responses Magento marked as cacheable
if (beresp.http.X-Magento-Tags) {
set beresp.do_esi = true;
set beresp.ttl = 86400s;
}
}
5. ESI and Alpine.js: dynamic islands inside cached pages
Pure SSG regularly fails at personalization, because a pre-built file is identical for every visitor. Magento has solved this problem for years via Edge Side Includes (ESI): the main page stays fully cacheable while individual fragments such as the mini cart, customer greeting or per-customer-group price are marked as separate, uncached sub-requests that Varnish assembles at the edge before the response reaches the browser. The rest of the page stays in cache, only the genuinely variable surface is recomputed per request.
For purely client-side reactive elements, such as the state of an "add to cart" button or a quantity selector with live stock, Hyva uses Alpine.js components with x-data. These are small, deliberately hydrated interaction islands without a full SPA runtime running in the background, conceptually comparable to the islands architecture popularized by Astro, just without a separate JavaScript framework, anchored directly in the server-rendered HTML. Combined, ESI and Alpine.js deliver exactly the outcome an SSG-plus-ISR stack with an islands architecture is aiming for: a static, cacheable shell with deliberately dynamic fragments, just without an upfront build step for the shell itself.
<!-- product/view.phtml (Hyva): ESI-included price fragment inside a fully cached page -->
<div class="product-price-wrapper">
<esi:include src="/esi/catalog/product/price/id/{{$product->getId()}}" />
</div>
<!-- Alpine.js island: reactive stock check without a JS framework runtime -->
<div x-data="{
qty: 1,
stock: null,
async checkStock() {
const res = await fetch(`/rest/V1/stockItems/{{$product->getSku()}}`);
this.stock = await res.json();
}
}"
x-init="checkStock()">
<span x-show="stock && stock.qty > 0" class="text-green-700">In stock</span>
<span x-show="stock && stock.qty <= 0" class="text-red-600">Out of stock</span>
</div>
6. Cache invalidation: tags instead of rebuild windows
Magento tags every block and every page with the IDs of the entities involved, such as product, category or CMS page ID. When a record is saved, Magento sends targeted BAN requests to Varnish that invalidate exactly the affected tags. This happens synchronously at save time, with no fixed time window and without a visitor ever seeing stale content, because the next request directly triggers a fresh cache miss and re-renders.
The ISR approach with webhook revalidation operates under a different consistency model. A content change triggers a webhook that either sets a time window until the next regeneration (stale-while-revalidate, in which visitors knowingly see stale content) or kicks off an on-demand rebuild for the affected paths. Both bring their own failure modes: concurrent webhook calls can overlap, a failed rebuild silently stays stale, and a cache miss after a broad invalidation can trigger a thundering herd against the origin server.
The core difference can be stated precisely: Varnish tag invalidation invalidates exactly what changed, at the moment it changed. ISR webhooks trade that precision for a simpler build architecture, paid for with a time-based staleness compromise that is rarely acceptable in a transactional store with prices and stock levels.
<!-- catalog_category_view.xml: cache lifetime for rarely-changing vs. dynamic blocks -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="category.description">
<arguments>
<!-- Rarely-changing CMS-style content: long TTL, effectively SSG-equivalent -->
<argument name="cache_lifetime" xsi:type="number">604800</argument>
</arguments>
</referenceBlock>
<referenceBlock name="product.price.render.default">
<arguments>
<!-- Price block excluded from the page cache, rendered per request via ESI -->
<argument name="cache_lifetime" xsi:type="number">0</argument>
</arguments>
</referenceBlock>
</body>
</page>
7. Prerendering services for crawlers: the pattern and its limits
The dynamic rendering pattern exists because client-side rendered SPAs cause problems for crawlers and bots: JavaScript execution is expensive, budget-limited or simply unreliable for many crawling systems. Services such as Prerender.io or Rendertron render the page ahead of time in a headless Chrome process, cache the result, and serve it specifically to recognized bot user agents, while human visitors continue to receive the client-side rendered bundle.
This solution brings its own, second cache invalidation system that has to be kept in sync with the actual application: stale snapshots, an additional rendering fleet that needs monitoring, and in the worst case a discrepancy between what bots see and what real users see. For Hyva stores this entire pattern is structurally irrelevant: since Magento always delivers fully formed HTML server-side, there is no gap between a client-rendered user view and a separate bot view that would need to be kept in sync. Every requester, human or bot, receives exactly the same, already-finished response from the same cache. That is a mechanical property of the rendering model, not a ranking argument.
8. When a headless or hybrid approach is still justified
There are real scenarios where an SSG or hybrid architecture is technically justified. In genuine omnichannel setups, where a single commerce backend serves native apps, a web frontend and in-store kiosk systems at the same time, a fully static delivery of pure marketing content without any origin dependency can make sense, especially in cold-start situations where even the first cache miss should be avoided. Extreme, short-lived traffic spikes, such as time-limited flash sale campaigns, can also benefit from a static delivery with no origin round trip at all, offering a safety margin.
Also reasonable: teams that already run a decoupled marketing or content site (for example on Astro) separate from the transactional store split responsibility cleanly by content type. For globally distributed audiences, the edge distribution of purely static assets can also outperform a single, even well-configured, Magento origin location. In all of these cases, scoping matters: an SSG layer pays off for immutable, non-transactional content, not for product, price or checkout pages, which should stay on Magento's proven FPC path.
9. Decision framework: weighing cost against benefit
A workable decision framework can be reduced to a few questions. Does the content change per request, such as price, stock level or cart state? Then server rendering with FPC and ESI remains the right choice, an SSG build solves nothing here, it just shifts the problem into a staleness window. Does the content change rarely and identically for every visitor, such as a CMS page or a category description? Then FPC with a long TTL already delivers SSG-equivalent latency, with no additional build pipeline needed.
Is the real friction the indexability of JavaScript-heavy content for crawlers? That problem is already structurally solved in a server-rendered stack, a prerendering layer here would be a solution to a problem that does not exist. Is the actual driver an architectural decision, such as genuine omnichannel or a deliberately separate marketing site? Then evaluating a hybrid approach is worthwhile, but scoped tightly to non-transactional content. The table below summarizes the key dimensions of that trade-off.
| Dimension | SSG/Headless Stack | Magento + Hyva + FPC |
|---|---|---|
| Build complexity | Separate build pipeline, artifact store, CDN invalidation | No build step, FPC materializes lazily on first request |
| Content freshness | Stale window until next rebuild or revalidate | Tag-based purge at save time, no fixed time window |
| Cache invalidation | Webhook chains with race condition risk | Varnish BAN on exact entity tags |
| Personalization | Requires additional client-side rehydration | ESI/Alpine islands directly in server HTML |
| Infrastructure cost | Build server, artifact store, CDN, separate backend | A single origin stack of PHP-FPM and Varnish |
The comparison is not a blanket "SSG is bad", it is a clear cost calculation: every additional component in the SSG pipeline is one more point where operations, monitoring and debugging effort has to be invested. For a Magento store with a Hyva theme, much of that cost is already covered by the existing FPC and ESI mechanism, without creating a second deployment target.
Mironsoft
Caching architecture, Varnish FPC and Hyva performance for Magento stores
Does your store actually need its own SSG pipeline?
We analyze your existing caching and rendering architecture, show what Varnish FPC and Hyva already cover, and, where it truly pays off, build a lean, targeted hybrid approach for the cases that need one.
FPC audit
Review and optimize cache hit rate, tag configuration and ESI fragments
ESI/Alpine islands
Cleanly extract dynamic fragments for price, stock and cart state
Hybrid consulting
An honest assessment of whether a headless layer adds value for your use case
10. Summary
Static Site Generation, Incremental Static Regeneration and prerendering services solve real problems, but mostly problems that are already structurally solved in Magento with a Hyva theme through Varnish Full Page Cache, tag-based invalidation and ESI-backed dynamic islands. A cache hit in FPC delivers the same latency as a static file, just without a separate build server, artifact store or CDN invalidation step. Personalized content such as prices and stock levels can be pulled out of the cache selectively via ESI and Alpine.js, instead of making the entire page uncacheable or requiring a second rehydration layer on the client.
The decisive difference lies in the invalidation model: Magento's tag-based purge invalidates exactly what changed, synchronously with the save operation. ISR and webhook-based rebuilds instead negotiate a time-based staleness window, which is rarely acceptable for transactional content. An additional SSG pipeline is technically worthwhile only in narrow scenarios such as genuine omnichannel setups or a deliberately separate marketing site, not as a blanket replacement for a functioning full page cache.
Prerendering and SSG hybrid strategies for stores, the essentials at a glance
Cache model
Varnish FPC materializes HTML lazily on the first miss, functionally equivalent to static files, without a build pipeline.
Dynamic islands
ESI for server-side fragments, Alpine.js x-data for client-side interaction, both without an SPA runtime.
Invalidation
Tag-based Varnish purge at save time instead of a time-based ISR staleness window via webhooks.
When hybrid makes sense
Only for genuine omnichannel setups or a separate marketing site, scoped tightly to non-transactional content.