Using Edge Functions for On‑Demand Page Regeneration in a Jamstack Site
Learn how to add a stateless Edge Function to a Jamstack site for on‑demand page regeneration, including requirements, minimal design, trust boundaries, operational checks, and failure modes.
09 Sept 2025, 09:50 UTC

Problem
Content updates in a Jamstack site traditionally require a full rebuild and redeploy, which can take minutes and delay the appearance of new information. For frequently changing pages (e.g., blog posts, product listings) this rebuild latency hurts editor experience and can serve stale content to visitors.
Requirements
- Serve fresh HTML for a page within seconds of a content change.
- Keep the majority of traffic served from the CDN edge cache to maintain low latency and low origin load.
- Avoid introducing stateful dependencies that would increase cold‑start latency or complicate scaling.
- Preserve the existing static‑site build pipeline for pages that do not need regeneration.
Smallest Suitable Design
The design adds an Edge Function that intercepts requests for a specific route pattern (e.g., /blog/*). On a cache miss, the function fetches the latest content from a headless CMS, renders the page using a templating library, and returns the HTML. The response is cached by the CDN with a short‑lived Cache‑Control: max‑age=60 header, allowing subsequent requests to be served from the edge until the next content update triggers a purge.
Minimal components
- Static site assets (HTML, CSS, JS) built once and deployed to the CDN.
- Edge Function code (stateless, < 50 ms init) deployed to the same edge platform.
- Webhook from the CMS that purges the specific URL pattern when content is published.
Trust & Data Boundaries
The Edge Function runs in a sandbox provided by the edge platform (e.g., Vercel Edge Runtime, Cloudflare Workers). It trusts only:
- The CMS endpoint (must be accessed over HTTPS with a token scoped to read‑only content).
- Environment variables injected at deploy time (e.g.,
CMS_TOKEN). - The request path and query string (no reliance on cookies or headers for security decisions).
No user‑generated data is stored; the function does not write to a database or filesystem, keeping the trust surface minimal.
Operational Checks
After deploying the Edge Function, verify the following:
- Latency measurement – Run
curl -w "%{time_total}\n" -s -o /dev/null https://example.com/blog/my-postfrom a location near the edge. Compare the time to a static asset request (https://example.com/_next/static/css/main.css). Expect the first request after a purge to be a few tens of milliseconds higher due to the function execution, but subsequent requests should match static latency. - Cache headers – Inspect the response:
curl -I https://example.com/blog/my-post. Look forCache‑Control: max‑age=60andAgeincreasing on repeat calls. - CDN log verification – In the provider’s dashboard, filter logs for the path
/blog/*. After a content update triggered by the CMS webhook, confirm aMISSfollowed by aHITwithin themax‑agewindow.
Example Edge Function (Vercel)
// /edge-functions/blog.js
import { renderBlogPost } from './lib/render.js';
export const config = { runtime: 'edge' };
export default async function handler(request) {
const { pathname } = new URL(request.url);
const slug = pathname.replace(/^\/blog\//, '');
// Fetch latest content from CMS (stateless, no caching inside function)
const res = await fetch(`https://cms.example.com/api/posts/${slug}`, {
headers: { Authorization: `Bearer ${process.env.CMS_TOKEN}` },
});
if (!res.ok) return new Response('Not Found', { status: 404 });
const data = await res.json();
const html = await renderBlogPost(data);
return new Response(html, {
headers: {
'Content-Type': 'text/html; charset=utf-8',
'Cache-Control': 'max-age=60, stale-while-revalidate=30',
},
});
}
Deploy with vercel --prod (requires access to the Vercel project and permission to create edge functions).
Failure Modes
- Cold start latency – If the edge platform has not instantiated the function recently, the first request may incur 100‑300 ms extra latency. Mitigation: keep the function small, avoid heavy imports, and enable "always‑on" or warm‑pool features if offered by the provider.
- CMS downtime – The function will return a 502 or custom error if the CMS is unreachable. Implement a fallback to serve the last known good HTML from the edge cache (stale‑while‑revalidate) or a static error page.
- Cache‑busting misconfiguration – If the webhook fails to purge the URL, stale content may be served beyond the intended freshness window. Monitor the purge success rate via CMS webhook logs and set up an alert on missing purges.
- Vendor lock‑in – Code relies on the edge platform’s runtime APIs (e.g., Vercel’s
fetchbehavior). Moving to another provider may require adjusting the function to match the new runtime’s constraints.
Conditions That Would Change the Design
- If the site requires personalized content per user (e.g., auth‑based views), the edge function would need to incorporate user‑specific data, breaking the stateless assumption and increasing complexity; a hybrid approach with client‑side fetching might be preferable.
- When traffic spikes cause frequent cold starts that exceed latency budgets, consider moving to a traditional server‑side rendering service with persistent instances, or increase the edge function’s warm‑pool size.
- If the CMS provides real‑time webhook payloads that include the rendered HTML, the edge function could become a simple pass‑through, eliminating the need for a templating library and reducing compute cost.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.