How I Build Fast, Secure Sites with Jamstack and Next.js
How I approach Jamstack builds for clients with Next.js and a headless CMS, plus when the architecture is the right call and when it is not.
Most of the client sites I ship run on some version of the Jamstack: pre-rendered pages, a headless CMS for content, a handful of APIs for the dynamic parts, and a CDN doing the heavy lifting up front. The name sounds like a product, but it is really just a set of decisions about where work happens. Push as much as you can to build time and to the edge, and keep the runtime surface small. Here is how I think about it on real projects and where I draw the line.
What a Jamstack build actually looks like for me
On a typical content-heavy site I reach for Next.js paired with Sanity as the headless CMS. Content lives in Sanity, editors work in a clean studio, and Next.js pulls that content at build time or revalidates it on a schedule. The pages get statically generated and served from a CDN, so the first byte comes from a cache near the user instead of a server spinning up a database query on every request.
The dynamic pieces still exist, they just move. A contact form posts to a serverless function. Search hits an API. A cart talks to Shopify's Storefront API. The point is that the marketing pages, blog, and docs are flat files, and only the genuinely interactive parts call out to a service. That split keeps the bulk of the site cheap to serve and hard to break.
I lean on Next.js incremental static regeneration so editors do not wait for a full rebuild to see changes. A page can be cached, then quietly regenerated in the background after a set interval or when a webhook from the CMS fires. Clients get the speed of static with most of the freshness of a server-rendered app.
The performance and security payoff
Performance is the obvious win. When HTML is already built and sitting on a CDN, there is no server render and no database round trip in the critical path. Pages arrive fast from a nearby edge node, Core Web Vitals improve almost for free, and the site holds up under a traffic spike because you are serving cached files, not running compute per visitor.
Security is the quieter benefit, and on the medical and telehealth work I have done it matters as much as speed. A static front end has very little to attack. There is no CMS admin panel exposed on the public domain, no database connection sitting behind every page, no server-side template waiting to be injected. The CMS lives behind its own auth, the APIs are scoped and rate-limited, and the public site is mostly read-only output. You shrink the attack surface by design rather than patching it later.
It also forces clean boundaries. Secrets stay in serverless functions and environment variables, never in the client bundle. Each integration, whether it is a payment provider or a scheduling API, talks through a narrow endpoint I control instead of being wired directly into the page. When something does go wrong, the blast radius is small.
When Jamstack is the right call, and when it is not
Jamstack shines when content changes far less often than it gets read. Marketing sites, blogs, documentation, landing pages, and storefronts with a manageable catalog are a great fit. If the client wants a fast, stable site that a non-technical team can edit through a CMS and that costs little to host, this is usually the architecture I recommend.
It gets awkward when the app is highly dynamic and personalized per user on every view. A dashboard that shows live data, a feed unique to each logged-in account, or a tool where almost nothing can be cached does not gain much from static generation. You can still use Next.js, you just lean on server rendering and APIs instead, and at that point you are building an app, not a Jamstack site. A huge catalog with hundreds of thousands of pages also pushes build times in the wrong direction unless you are careful with on-demand revalidation.
My rule of thumb is simple: if the page is the same for most people most of the time, pre-render it and put it on a CDN. If the page is different for everyone on every visit, render it on demand. Most real client sites are a mix, and the work is deciding which pages fall on which side of that line. Get that split right and you end up with a site that is fast for users, calm to operate, and cheap to keep running.