Web Development

Jamstack plus headless commerce for a boutique retail client

DEV

A boutique retail client with a small catalog wanted a storefront that felt more like an editorial magazine than a typical ecommerce template, without taking on the operational weight of a full platform like Magento for what is, in truth, a modest number of products.

Why we ruled out a traditional platform first

We priced out a conventional Magento build as a baseline before recommending anything else, since it is the platform most retail clients expect by default and we wanted a fair comparison rather than steering the client toward our own architectural preference without justification. Magento's template system, however, would have fought against the client's specific ambition for editorially rich, magazine-style product pages, and the platform's operational overhead — its own hosting requirements, a more involved upgrade cadence, a heavier admin interface than this client's small team really needed — was a real cost for a catalog this size that did not clearly buy the client anything in return.

The architecture we landed on

  • A statically generated frontend, pulling product and inventory data at build time from a headless commerce API, rather than a platform rendering pages dynamically on every request
  • Client-side calls reserved only for genuinely dynamic pieces — cart contents and checkout — with everything else pre-rendered as static HTML
  • A CDN serving the pre-rendered pages, giving the client near-instant page loads regardless of where a visitor is located
  • A webhook from the commerce API's inventory system triggering an automatic site rebuild whenever the catalog changes, rather than requiring a manual redeploy for every new product or price change

What this meant for the editorial team's day-to-day workflow

The editorial team lays out rich content around products using the same static-site tooling as the rest of the marketing pages, rather than being boxed into a commerce platform's more rigid template system. A product page can include a full editorial narrative, custom photography layouts, and embedded video alongside the standard product details, none of which needed a developer's involvement to assemble once the underlying content structure was in place, which was a meaningful win for a small team that does not have a developer on staff for routine content updates.

The rebuild-latency tradeoff, and how we mitigated it

Rebuilding the static site on every inventory change added a small amount of deploy latency compared to a fully dynamic storefront, since a price change or a new product does not appear instantly the way it would on a server rendering pages live from a database on every request. We mitigated this with the webhook-triggered rebuild described above, which brings a typical inventory update live within a few minutes rather than requiring someone to remember to trigger a manual deploy, and for a catalog this size, a few minutes of lag between an inventory change and it appearing live has not been a real problem for the client in practice.

Where this approach would not have worked

We were upfront with the client that this architecture has real limits that would matter for a different kind of retailer — a catalog with thousands of frequently changing products would push the rebuild time high enough to become a genuine operational problem, and a business needing real-time inventory accuracy down to the second, such as a flash-sale model with tightly constrained stock, would find the rebuild-triggered update model too slow regardless of how quickly we can get a rebuild to complete. We would recommend a fully dynamic, server-rendered approach for either of those situations rather than forcing this client's architecture onto a business it does not actually fit.

Handling checkout and cart without a full backend of our own

Cart state lives in the browser until checkout, at which point the headless commerce API's own checkout flow takes over entirely, meaning we never had to build or maintain payment processing, tax calculation, or order management ourselves — all of that lives inside the commerce platform, accessed through its API, with our static frontend responsible only for presentation and for handing off to the commerce platform's hosted checkout at the right moment. This kept our own application's actual surface area small, which mattered for a project with a modest budget that could not have absorbed the cost of building and securing payment handling from scratch.

SEO considerations for a statically generated storefront

A statically generated site has a real SEO advantage out of the box, since every page is fully rendered HTML available to a search engine crawler immediately, with no client-side JavaScript execution required to see the actual product content the way a purely client-rendered single-page application would need. We paired this with generated structured data for each product page, pulled from the same commerce API data used to build the page itself, which has helped several of the client's products appear with rich search result snippets — price, availability, rating — that a less carefully built storefront would not automatically get.

What we would scope differently on a similar project next time

Knowing what we know now, we would build the inventory-change webhook and rebuild pipeline earlier in the project timeline rather than treating it as a late-stage addition, since it ended up being more central to how the client actually experiences using the site day to day than our original project plan anticipated. We originally scoped it as a smaller, secondary task behind the storefront's visual design, and in hindsight the two deserved closer to equal priority from the very start of the engagement.

Results

For a smaller catalog where rebuild time stays low, the approach gave this client a faster, more distinctive site than a conventional ecommerce platform would have, at a lower ongoing hosting cost, since serving pre-rendered static pages from a CDN costs a fraction of running an always-on dynamic commerce platform for a catalog this size. The client's own team has also been able to make routine content and inventory updates entirely on their own, without needing to come back to us for the kind of small changes that would have required a developer's involvement on a more conventional platform.

Handling out-of-stock states cleanly in a statically generated context

A product going out of stock between scheduled rebuilds is a real edge case a statically generated storefront has to handle deliberately, since the pre-rendered page does not automatically know that inventory changed the moment it actually does. We addressed this with a lightweight client-side stock check that runs against the live commerce API when a shopper views a product page or attempts to add an item to their cart, overriding the statically rendered "in stock" state if inventory has actually changed since the last build, which keeps the fast static-page experience for the common case while still preventing a shopper from completing a purchase for an item that sold out minutes after the last rebuild.

A concrete performance number worth sharing

On a representative product page, the statically generated site's full page load, measured from an empty cache, came in well under what the client's previous conventional ecommerce platform delivered for a comparable page, largely because there is no server-side template rendering or database query happening on the request path at all — the CDN is simply serving a pre-built file. This is the kind of concrete, client-visible number that made the architecture's benefit tangible to a non-technical stakeholder in a way that an abstract description of "static site generation" on its own would not have.

Preview functionality for unpublished product content

The editorial team occasionally wants to preview an unpublished product page — new photography, updated copy — before it goes live to shoppers, which a purely statically generated site does not support out of the box, since an unpublished page by definition has no pre-built static file yet. We built a small preview mode that renders a specific unpublished product directly from the commerce API's draft data on demand, bypassing the static build entirely for that one preview request, giving editors the same "see it before it's live" confidence a traditional dynamic platform would offer natively. This preview mode is deliberately separate infrastructure from the main storefront, accessible only via a private link shared with the editorial team, rather than a general-purpose feature exposed to shoppers, keeping its added complexity contained to the one workflow that actually needs it.

← Back to the journal

Have a project in mind?
Let’s talk.

Tell us where you are and where you want to go. We'll map the fastest route between the two.

Currently accepting new clients