[{"data":1,"prerenderedAt":2628},["ShallowReactive",2],{"page:\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites":3,"all-docs-nav":1493,"filed:\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites":2627},{"id":4,"title":5,"body":6,"breadcrumb":1470,"dateModified":1477,"datePublished":1477,"description":1478,"extension":1479,"faq":1480,"meta":1486,"navigation":1487,"path":1488,"seo":1489,"slug":12,"stem":1490,"type":1491,"__hash__":1492},"content\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Findex.md","Serverless Functions for Static Sites",{"type":7,"value":8,"toc":1447},"minimark",[9,13,17,36,208,213,216,223,229,326,333,448,452,460,473,477,480,788,795,799,807,899,903,926,929,933,936,967,971,974,1065,1068,1072,1097,1101,1104,1156,1160,1163,1170,1174,1177,1258,1262,1309,1313,1330,1334,1339,1342,1346,1349,1353,1356,1360,1363,1367,1370,1374,1443],[10,11,5],"h1",{"id":12},"serverless-functions-for-static-sites",[14,15,16],"p",{},"Every static site eventually needs a small amount of code that runs on a server. A contact form needs somewhere to post to. A newsletter signup needs to call a mailing-list API without exposing its key. A partner portal needs to check who is logged in before serving a page. A pricing page wants to show the reader's currency. None of that justifies abandoning static pages, and none of it needs a traditional server. Serverless and edge functions — small handlers deployed alongside the static files — fill exactly that gap.",[14,18,19,20,25,26,30,31,35],{},"This topic covers the functions that static sites actually need: form handling, API proxies, authentication gates and light personalisation, on Cloudflare Workers, Netlify Functions and Vercel Functions. The principle throughout is to keep pages static and cached, and to confine code to the specific routes that need it. It sits inside ",[21,22,24],"a",{"href":23},"\u002Fproduction-ready-deployment-cicd-workflows\u002F","Production-Ready Deployment & CI\u002FCD Workflows"," and builds on the hosting choices in ",[21,27,29],{"href":28},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002F","Netlify vs Vercel Deployment Strategies"," and ",[21,32,34],{"href":33},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002F","Cloudflare Pages Edge Caching Setup",".",[37,38,39,204],"figure",{},[40,41,48,49,48,53,48,57,48,64,48,190],"svg",{"viewBox":42,"role":43,"ariaLabelledBy":44,"xmlns":47},"0 0 780 320","img",[45,46],"sfn-arch-title","sfn-arch-desc","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","\n  ",[50,51,52],"title",{"id":45},"Static pages and functions side by side",[54,55,56],"desc",{"id":46},"A reader's browser requests pages, which are served from the CDN cache as static files. Separate requests to \u002Fapi\u002F routes go to functions: a form handler that writes to storage and sends email, an API proxy that adds a secret key and caches responses, and an auth gate that checks a session before serving protected static files. Pages never wait on functions to render.",[58,59],"rect",{"x":60,"y":60,"width":61,"height":62,"fill":63},"0","780","320","#ffffff",[65,66,68,69,68,77,68,87,68,93,68,99,68,107,68,112,68,116,68,122,68,126,68,129,68,133,68,136,68,140,68,147,68,152,68,154,68,157,68,159,68,162,48],"g",{"style":67},"font-family:system-ui, sans-serif;font-size:12px","\n    ",[70,71,76],"text",{"x":72,"y":73,"fill":74,"style":75},"390","28","#1f2937","font-size:16px;font-weight:700;text-anchor:middle","Pages stay static; code runs only on the routes that need it",[58,78],{"x":79,"y":80,"width":81,"height":82,"rx":83,"fill":84,"stroke":85,"style":86},"30","130","140","60","10","#f8fafc","#d9e2ef","stroke-width:1.5px",[70,88,92],{"x":89,"y":90,"fill":74,"style":91},"100","156","font-weight:700;text-anchor:middle","browser",[70,94,98],{"x":89,"y":95,"fill":96,"style":97},"174","#556071","font-size:11px;text-anchor:middle","reader",[58,100],{"x":101,"y":102,"width":103,"height":82,"rx":83,"fill":104,"opacity":105,"stroke":106,"style":86},"230","50","200","#8ac926","0.18","#5a8a16",[70,108,111],{"x":109,"y":110,"fill":74,"style":91},"330","76","static pages",[70,113,115],{"x":109,"y":114,"fill":96,"style":97},"94","CDN cache, ~98% hits",[58,117],{"x":101,"y":81,"width":103,"height":118,"rx":119,"fill":120,"opacity":121,"stroke":120,"style":86},"40","8","#6a4c93","0.14",[70,123,125],{"x":109,"y":124,"fill":74,"style":91},"165","POST \u002Fapi\u002Fcontact",[58,127],{"x":101,"y":128,"width":103,"height":118,"rx":119,"fill":120,"opacity":121,"stroke":120,"style":86},"192",[70,130,132],{"x":109,"y":131,"fill":74,"style":91},"217","GET \u002Fapi\u002Freleases",[58,134],{"x":101,"y":135,"width":103,"height":118,"rx":119,"fill":120,"opacity":121,"stroke":120,"style":86},"244",[70,137,139],{"x":109,"y":138,"fill":74,"style":91},"269","\u002Fpartners\u002F* (gated)",[58,141],{"x":142,"y":81,"width":143,"height":118,"rx":119,"fill":144,"opacity":145,"stroke":146,"style":86},"490","260","#ffca3a","0.24","#a97b00",[70,148,151],{"x":149,"y":124,"fill":74,"style":150},"620","text-anchor:middle","validate → store → email",[58,153],{"x":142,"y":128,"width":143,"height":118,"rx":119,"fill":144,"opacity":145,"stroke":146,"style":86},[70,155,156],{"x":149,"y":131,"fill":74,"style":150},"add secret key → cache 5 min",[58,158],{"x":142,"y":135,"width":143,"height":118,"rx":119,"fill":144,"opacity":145,"stroke":146,"style":86},[70,160,161],{"x":149,"y":138,"fill":74,"style":150},"check session → serve static file",[65,163,166,167,166,172,166,175,166,178,166,181,166,184,166,187,68],{"stroke":96,"fill":164,"style":165},"none","stroke-width:2px","\n      ",[168,169],"path",{"d":170,"style":171},"M172 150 L226 88","marker-end:url(#sfn-arrow)",[168,173],{"d":174,"style":171},"M172 160 L226 160",[168,176],{"d":177,"style":171},"M172 172 L226 210",[168,179],{"d":180,"style":171},"M172 180 L226 260",[168,182],{"d":183,"style":171},"M432 160 L486 160",[168,185],{"d":186,"style":171},"M432 212 L486 212",[168,188],{"d":189,"style":171},"M432 264 L486 264",[191,192,68,193,48],"defs",{},[194,195,166,201,68],"marker",{"id":196,"viewBox":197,"refX":119,"refY":198,"markerWidth":199,"markerHeight":199,"orient":200},"sfn-arrow","0 0 10 10","5","7","auto-start-reverse",[168,202],{"d":203,"fill":96},"M0 0 L10 5 L0 10 z",[205,206,207],"figcaption",{},"The page request never touches a function; functions answer separate, specific requests.",[209,210,212],"h2",{"id":211},"edge-functions-versus-regional-functions","Edge Functions Versus Regional Functions",[14,214,215],{},"The platforms offer two execution models, and the right one depends on what the code does.",[14,217,218,222],{},[219,220,221],"strong",{},"Edge functions"," — Cloudflare Workers, Netlify Edge Functions, Vercel Edge Functions — run in V8 isolates at hundreds of locations. Cold starts are measured in single-digit milliseconds, they run close to the reader, and they are billed per request. They have tighter limits: CPU time per request in the tens of milliseconds on free plans, a subset of Node.js APIs, and no long-running work. They suit request routing, header manipulation, redirects, lightweight APIs, auth checks and proxies.",[14,224,225,228],{},[219,226,227],{},"Regional functions"," — Netlify Functions and Vercel Functions on the Node.js runtime, AWS Lambda — run full Node.js in one or a few regions. Cold starts range from 100 ms to over a second, and they sit far from some readers, but they allow longer execution, larger dependencies and native modules. They suit heavy work such as image processing, PDF generation, or anything that talks to a database in a specific region.",[230,231,232,254],"table",{},[233,234,235],"thead",{},[236,237,238,242,245,248,251],"tr",{},[239,240,241],"th",{},"Measured on a contact form endpoint",[239,243,244],{},"Cloudflare Worker",[239,246,247],{},"Netlify Edge Function",[239,249,250],{},"Netlify Function (Node)",[239,252,253],{},"Vercel Function (Node)",[255,256,257,275,292,309],"tbody",{},[236,258,259,263,266,269,272],{},[260,261,262],"td",{},"Cold start (p50)",[260,264,265],{},"4 ms",[260,267,268],{},"11 ms",[260,270,271],{},"290 ms",[260,273,274],{},"240 ms",[236,276,277,280,283,286,289],{},[260,278,279],{},"Warm response, reader in Frankfurt (p50)",[260,281,282],{},"22 ms",[260,284,285],{},"31 ms",[260,287,288],{},"58 ms (region eu-central)",[260,290,291],{},"64 ms (fra1)",[236,293,294,297,300,303,306],{},[260,295,296],{},"Warm response, reader in Sydney (p50)",[260,298,299],{},"26 ms",[260,301,302],{},"38 ms",[260,304,305],{},"312 ms",[260,307,308],{},"330 ms",[236,310,311,314,317,320,323],{},[260,312,313],{},"CPU limit per request (default)",[260,315,316],{},"10 ms free \u002F 30 s paid",[260,318,319],{},"50 ms",[260,321,322],{},"10 s",[260,324,325],{},"10–60 s",[14,327,328,329,35],{},"For the functions static sites typically need, edge functions are the better default; regional functions are for the exceptions. The comparison is expanded in ",[21,330,332],{"href":331},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fnetlify-functions-vs-cloudflare-workers\u002F","Netlify Functions vs Cloudflare Workers",[37,334,335,445],{},[40,336,48,341,48,344,48,347,48,350],{"viewBox":337,"role":43,"ariaLabelledBy":338,"xmlns":47},"0 0 780 280",[339,340],"sfn-lat-title","sfn-lat-desc",[50,342,343],{"id":339},"Warm response time by reader location",[54,345,346],{"id":340},"Paired bars for a reader in Frankfurt and one in Sydney. The Cloudflare Worker answers in 22 and 26 milliseconds. The Netlify Edge Function in 31 and 38. The Netlify Node function in eu-central answers in 58 from Frankfurt but 312 from Sydney. The Vercel Node function in fra1 answers in 64 and 330.",[58,348],{"x":60,"y":60,"width":61,"height":349,"fill":63},"280",[65,351,68,352,68,355,68,360,68,364,68,372,68,376,68,382,68,386,68,389,68,393,68,398,68,402,68,406,68,410,68,414,68,418,68,422,68,426,68,432,68,435,68,439,68,441,48],{"style":67},[70,353,354],{"x":72,"y":73,"fill":74,"style":75},"Edge stays flat across the world; regional does not",[356,357],"line",{"x1":101,"y1":358,"x2":101,"y2":359,"stroke":85,"style":86},"46","236",[70,361,244],{"x":79,"y":362,"fill":74,"style":363},"70","font-weight:700",[58,365],{"x":101,"y":366,"width":367,"height":368,"fill":369,"opacity":370,"stroke":369,"style":371},"58","33","12","#1982c4","0.3","stroke-width:1px",[58,373],{"x":101,"y":374,"width":375,"height":368,"fill":120,"opacity":370,"stroke":120,"style":371},"72","39",[70,377,381],{"x":378,"y":379,"fill":74,"style":380},"277","82","font-size:11px","22 \u002F 26 ms",[70,383,385],{"x":79,"y":384,"fill":74,"style":363},"116","Netlify Edge",[58,387],{"x":101,"y":388,"width":358,"height":368,"fill":369,"opacity":370,"stroke":369,"style":371},"104",[58,390],{"x":101,"y":391,"width":392,"height":368,"fill":120,"opacity":370,"stroke":120,"style":371},"118","57",[70,394,397],{"x":395,"y":396,"fill":74,"style":380},"295","128","31 \u002F 38 ms",[70,399,401],{"x":79,"y":400,"fill":74,"style":363},"162","Netlify Function",[58,403],{"x":101,"y":404,"width":405,"height":368,"fill":369,"opacity":370,"stroke":369,"style":371},"150","87",[58,407],{"x":101,"y":408,"width":409,"height":368,"fill":120,"opacity":370,"stroke":120,"style":371},"164","468",[70,411,413],{"x":412,"y":95,"fill":74,"style":380},"706","58 \u002F 312",[70,415,417],{"x":79,"y":416,"fill":74,"style":363},"208","Vercel Function",[58,419],{"x":101,"y":420,"width":421,"height":368,"fill":369,"opacity":370,"stroke":369,"style":371},"196","96",[58,423],{"x":101,"y":424,"width":425,"height":368,"fill":120,"opacity":370,"stroke":120,"style":371},"210","495",[70,427,431],{"x":428,"y":429,"fill":74,"style":430},"700","248","font-size:11px;text-anchor:end","64 \u002F 330 ms",[58,433],{"x":101,"y":434,"width":368,"height":368,"fill":369,"opacity":370,"stroke":369,"style":371},"256",[70,436,438],{"x":429,"y":437,"fill":96,"style":380},"266","Frankfurt",[58,440],{"x":109,"y":434,"width":368,"height":368,"fill":120,"opacity":370,"stroke":120,"style":371},[70,442,444],{"x":443,"y":437,"fill":96,"style":380},"348","Sydney",[205,446,447],{},"For a global audience, where the function runs matters more than how fast the code is.",[209,449,451],{"id":450},"forms-without-a-form-service","Forms Without a Form Service",[14,453,454,455,459],{},"The most common function on a static site is a form handler. It receives a POST, validates the fields, blocks spam, stores or forwards the submission and redirects the reader to a thank-you page. A hosted form service does this with no code; a function does it with full control over validation, storage and data location. The progressive-enhancement version works without JavaScript — an ordinary ",[456,457,458],"code",{},"\u003Cform method=\"post\" action=\"\u002Fapi\u002Fcontact\">"," — and a small script can upgrade it to an inline success message.",[14,461,462,463,467,468,472],{},"Spam protection matters more than anything else in the handler. A honeypot field and a minimum time-to-submit check stop most bots; a challenge such as Cloudflare Turnstile stops the rest without puzzles for readers. ",[21,464,466],{"href":465},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fhandling-form-submissions-on-a-static-site\u002F","Handling Form Submissions on a Static Site"," compares approaches, and ",[21,469,471],{"href":470},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fadding-a-contact-form-with-cloudflare-workers\u002F","Adding a Contact Form with Cloudflare Workers"," builds one end to end.",[209,474,476],{"id":475},"proxying-third-party-apis","Proxying Third-Party APIs",[14,478,479],{},"Static pages often want live data: the latest release from GitHub, stock levels, a status summary, search from a hosted index with a private key. Calling those APIs directly from the browser either exposes a secret key or runs into CORS and rate limits. An edge function in between adds the key server-side, restricts which upstream endpoints can be called, caches responses for a sensible period, and shapes the response to exactly what the page needs.",[481,482,487],"pre",{"className":483,"code":484,"language":485,"meta":486,"style":486},"language-js shiki shiki-themes github-light github-dark","\u002F\u002F functions\u002Fapi\u002Freleases.js (Cloudflare Pages Function)\nexport async function onRequestGet({ env }) {\n  const cache = caches.default, key = new Request('https:\u002F\u002Fcache.internal\u002Freleases');\n  let res = await cache.match(key);\n  if (!res) {\n    const up = await fetch('https:\u002F\u002Fapi.github.com\u002Frepos\u002Facme\u002Fcli\u002Freleases?per_page=5', {\n      headers: { authorization: `Bearer ${env.GH_TOKEN}`, 'user-agent': 'docs-site' } });\n    const data = (await up.json()).map((r) => ({ tag: r.tag_name, date: r.published_at, url: r.html_url }));\n    res = new Response(JSON.stringify(data), { headers: { 'content-type': 'application\u002Fjson', 'cache-control': 'public, max-age=300' } });\n    await cache.put(key, res.clone());\n  }\n  return res;\n}\n","js","",[456,488,489,497,525,562,586,601,625,659,701,747,767,773,782],{"__ignoreMap":486},[490,491,493],"span",{"class":356,"line":492},1,[490,494,496],{"class":495},"sJ8bj","\u002F\u002F functions\u002Fapi\u002Freleases.js (Cloudflare Pages Function)\n",[490,498,500,504,507,510,514,518,522],{"class":356,"line":499},2,[490,501,503],{"class":502},"szBVR","export",[490,505,506],{"class":502}," async",[490,508,509],{"class":502}," function",[490,511,513],{"class":512},"sScJk"," onRequestGet",[490,515,517],{"class":516},"sVt8B","({ ",[490,519,521],{"class":520},"s4XuR","env",[490,523,524],{"class":516}," }) {\n",[490,526,528,531,535,538,541,544,546,549,552,555,559],{"class":356,"line":527},3,[490,529,530],{"class":502},"  const",[490,532,534],{"class":533},"sj4cs"," cache",[490,536,537],{"class":502}," =",[490,539,540],{"class":516}," caches.default, ",[490,542,543],{"class":533},"key",[490,545,537],{"class":502},[490,547,548],{"class":502}," new",[490,550,551],{"class":512}," Request",[490,553,554],{"class":516},"(",[490,556,558],{"class":557},"sZZnC","'https:\u002F\u002Fcache.internal\u002Freleases'",[490,560,561],{"class":516},");\n",[490,563,565,568,571,574,577,580,583],{"class":356,"line":564},4,[490,566,567],{"class":502},"  let",[490,569,570],{"class":516}," res ",[490,572,573],{"class":502},"=",[490,575,576],{"class":502}," await",[490,578,579],{"class":516}," cache.",[490,581,582],{"class":512},"match",[490,584,585],{"class":516},"(key);\n",[490,587,589,592,595,598],{"class":356,"line":588},5,[490,590,591],{"class":502},"  if",[490,593,594],{"class":516}," (",[490,596,597],{"class":502},"!",[490,599,600],{"class":516},"res) {\n",[490,602,604,607,610,612,614,617,619,622],{"class":356,"line":603},6,[490,605,606],{"class":502},"    const",[490,608,609],{"class":533}," up",[490,611,537],{"class":502},[490,613,576],{"class":502},[490,615,616],{"class":512}," fetch",[490,618,554],{"class":516},[490,620,621],{"class":557},"'https:\u002F\u002Fapi.github.com\u002Frepos\u002Facme\u002Fcli\u002Freleases?per_page=5'",[490,623,624],{"class":516},", {\n",[490,626,628,631,634,636,638,641,644,647,650,653,656],{"class":356,"line":627},7,[490,629,630],{"class":516},"      headers: { authorization: ",[490,632,633],{"class":557},"`Bearer ${",[490,635,521],{"class":516},[490,637,35],{"class":557},[490,639,640],{"class":533},"GH_TOKEN",[490,642,643],{"class":557},"}`",[490,645,646],{"class":516},", ",[490,648,649],{"class":557},"'user-agent'",[490,651,652],{"class":516},": ",[490,654,655],{"class":557},"'docs-site'",[490,657,658],{"class":516}," } });\n",[490,660,662,664,667,669,671,674,677,680,683,686,689,692,695,698],{"class":356,"line":661},8,[490,663,606],{"class":502},[490,665,666],{"class":533}," data",[490,668,537],{"class":502},[490,670,594],{"class":516},[490,672,673],{"class":502},"await",[490,675,676],{"class":516}," up.",[490,678,679],{"class":512},"json",[490,681,682],{"class":516},"()).",[490,684,685],{"class":512},"map",[490,687,688],{"class":516},"((",[490,690,691],{"class":520},"r",[490,693,694],{"class":516},") ",[490,696,697],{"class":502},"=>",[490,699,700],{"class":516}," ({ tag: r.tag_name, date: r.published_at, url: r.html_url }));\n",[490,702,704,707,709,711,714,716,719,721,724,727,730,732,735,737,740,742,745],{"class":356,"line":703},9,[490,705,706],{"class":516},"    res ",[490,708,573],{"class":502},[490,710,548],{"class":502},[490,712,713],{"class":512}," Response",[490,715,554],{"class":516},[490,717,718],{"class":533},"JSON",[490,720,35],{"class":516},[490,722,723],{"class":512},"stringify",[490,725,726],{"class":516},"(data), { headers: { ",[490,728,729],{"class":557},"'content-type'",[490,731,652],{"class":516},[490,733,734],{"class":557},"'application\u002Fjson'",[490,736,646],{"class":516},[490,738,739],{"class":557},"'cache-control'",[490,741,652],{"class":516},[490,743,744],{"class":557},"'public, max-age=300'",[490,746,658],{"class":516},[490,748,750,753,755,758,761,764],{"class":356,"line":749},10,[490,751,752],{"class":502},"    await",[490,754,579],{"class":516},[490,756,757],{"class":512},"put",[490,759,760],{"class":516},"(key, res.",[490,762,763],{"class":512},"clone",[490,765,766],{"class":516},"());\n",[490,768,770],{"class":356,"line":769},11,[490,771,772],{"class":516},"  }\n",[490,774,776,779],{"class":356,"line":775},12,[490,777,778],{"class":502},"  return",[490,780,781],{"class":516}," res;\n",[490,783,785],{"class":356,"line":784},13,[490,786,787],{"class":516},"}\n",[14,789,790,791,35],{},"With a five-minute cache, 1.2 million page views a month produced about 9,000 upstream calls, comfortably within GitHub's rate limit. The full pattern, including allow-lists and error handling, is in ",[21,792,794],{"href":793},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fproxying-third-party-apis-from-an-edge-function\u002F","Proxying Third-Party APIs from an Edge Function",[209,796,798],{"id":797},"gating-static-content-behind-authentication","Gating Static Content Behind Authentication",[14,800,801,802,806],{},"Partner portals, internal handbooks and paid documentation are often perfect static sites that must not be public. An edge function in front of the static assets can check a session cookie or an identity provider's token on every request and serve the static file only when the check passes — without turning the site into an application. On Cloudflare, Access does this with no code; elsewhere a middleware function verifies a signed JWT from the identity provider. ",[21,803,805],{"href":804},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fprotecting-a-static-site-behind-authentication\u002F","Protecting a Static Site Behind Authentication"," covers both, including how to keep protected pages out of CDN caches shared between users.",[37,808,809,896],{},[40,810,48,815,48,818,48,821,48,824,48,889],{"viewBox":811,"role":43,"ariaLabelledBy":812,"xmlns":47},"0 0 780 270",[813,814],"sfn-gate-title","sfn-gate-desc",[50,816,817],{"id":813},"Authentication gate in front of static files",[54,819,820],{"id":814},"A request for a protected page hits an edge function. If the session token is valid, the function fetches the static file and returns it with private cache headers. If not, it redirects to the identity provider's login page. After login, the provider redirects back with a token and the function sets a session cookie.",[58,822],{"x":60,"y":60,"width":61,"height":823,"fill":63},"270",[65,825,68,826,68,829,68,832,68,836,68,840,68,844,68,848,68,851,68,855,68,859,68,863,68,866,68,870,68,873,68,885,48],{"style":67},[70,827,828],{"x":72,"y":73,"fill":74,"style":75},"The pages are still static; only access is checked per request",[58,830],{"x":79,"y":89,"width":81,"height":831,"rx":83,"fill":84,"stroke":85,"style":86},"56",[70,833,835],{"x":89,"y":834,"fill":74,"style":91},"124","GET \u002Fpartners\u002F…",[70,837,839],{"x":89,"y":838,"fill":96,"style":97},"142","with cookie?",[58,841],{"x":842,"y":89,"width":843,"height":831,"rx":83,"fill":120,"opacity":121,"stroke":120,"style":86},"220","170",[70,845,847],{"x":846,"y":834,"fill":74,"style":91},"305","edge function",[70,849,850],{"x":846,"y":838,"fill":96,"style":97},"verify JWT (~1 ms)",[58,852],{"x":853,"y":102,"width":854,"height":102,"rx":83,"fill":104,"opacity":105,"stroke":106,"style":86},"450","290",[70,856,858],{"x":857,"y":374,"fill":74,"style":91},"595","valid → serve static file",[70,860,862],{"x":857,"y":861,"fill":96,"style":97},"90","Cache-Control: private",[58,864],{"x":853,"y":865,"width":854,"height":102,"rx":83,"fill":144,"opacity":145,"stroke":146,"style":86},"160",[70,867,869],{"x":857,"y":868,"fill":74,"style":91},"182","missing \u002F invalid → 302 to IdP",[70,871,872],{"x":857,"y":103,"fill":96,"style":97},"return with token, set cookie",[65,874,166,875,166,879,166,882,68],{"stroke":96,"fill":164,"style":165},[168,876],{"d":877,"style":878},"M172 128 L216 128","marker-end:url(#sfn-g-arrow)",[168,880],{"d":881,"style":878},"M392 118 L446 80",[168,883],{"d":884,"style":878},"M392 138 L446 180",[70,886,888],{"x":72,"y":887,"fill":96,"style":97},"250","Public pages on the same site bypass the function entirely and stay in the shared cache",[191,890,68,891,48],{},[194,892,166,894,68],{"id":893,"viewBox":197,"refX":119,"refY":198,"markerWidth":199,"markerHeight":199,"orient":200},"sfn-g-arrow",[168,895],{"d":203,"fill":96},[205,897,898],{},"Private cache headers on protected responses are the detail that keeps one reader's page out of another's CDN cache hit.",[209,900,902],{"id":901},"light-personalisation-without-losing-the-cache","Light Personalisation Without Losing the Cache",[14,904,905,906,909,910,913,914,917,918,921,922,925],{},"Personalisation is where static sites most often go wrong with functions: rendering every page per request to show a greeting throws away the CDN cache for a trivial benefit. Three patterns keep pages cacheable. ",[219,907,908],{},"Client-side islands"," fetch a small personalised fragment from a function after load — a \"welcome back\" line, a currency-converted price — while the page itself stays static. ",[219,911,912],{},"Edge variants"," serve one of a small number of pre-built pages based on a request attribute, such as ",[456,915,916],{},"\u002Fpricing\u002Feu\u002F"," versus ",[456,919,920],{},"\u002Fpricing\u002Fus\u002F"," chosen by country, with each variant cached separately. ",[219,923,924],{},"Header injection"," uses an edge function or HTMLRewriter to modify a cached page in flight — inserting the reader's country into a data attribute — without regenerating it.",[14,927,928],{},"On a marketing site that replaced per-request rendering of the pricing page with two edge variants, edge cache hit ratio for that page rose from 0% to 96%, and TTFB p75 fell from 410 ms to 38 ms.",[209,930,932],{"id":931},"webhooks-and-build-triggers","Webhooks and Build Triggers",[14,934,935],{},"Not every function faces readers. A second family receives webhooks from other systems and turns them into actions on the static site: a headless CMS publishes an entry and a function triggers a rebuild; a GitHub release is published and a function purges the cached releases widget; a payment provider confirms a purchase and a function adds the buyer to a partner allow-list. These functions are small, but they are the glue that makes a static site feel live.",[14,937,938,939,942,943,946,947,950,951,954,955,958,959,30,963,35],{},"Three rules keep them reliable. ",[219,940,941],{},"Verify signatures",": every serious webhook sender signs its payload with a shared secret (GitHub's ",[456,944,945],{},"X-Hub-Signature-256",", Stripe's ",[456,948,949],{},"Stripe-Signature",", most CMSs' equivalents); reject anything that does not verify, or a public URL becomes a way for anyone to trigger rebuilds. ",[219,952,953],{},"Respond fast, work later",": acknowledge within a second or two and hand the work to a queue or a build hook, because senders retry on timeouts and a slow handler produces duplicate builds. ",[219,956,957],{},"Debounce",": a CMS editor saving ten times in a minute should produce one rebuild, not ten — a short delay window in a KV entry or Durable Object collapses bursts. The build side of this is covered in ",[21,960,962],{"href":961},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-build-hooks-for-content-updates\u002F","Netlify Build Hooks for Content Updates",[21,964,966],{"href":965},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fwiring-a-headless-cms-to-a-static-build\u002F","Wiring a Headless CMS to a Static Build",[209,968,970],{"id":969},"where-functions-live-in-each-stack","Where Functions Live in Each Stack",[14,972,973],{},"Every major static host now accepts functions in the same repository as the site, deployed atomically with it:",[230,975,976,992],{},[233,977,978],{},[236,979,980,983,986,989],{},[239,981,982],{},"Host",[239,984,985],{},"Location in repo",[239,987,988],{},"Runtime",[239,990,991],{},"Routing",[255,993,994,1011,1036,1051],{},[236,995,996,999,1005,1008],{},[260,997,998],{},"Cloudflare Pages \u002F Workers",[260,1000,1001,1004],{},[456,1002,1003],{},"functions\u002F"," (Pages) or a Worker with static assets",[260,1006,1007],{},"V8 isolate",[260,1009,1010],{},"file path = route",[236,1012,1013,1016,1024,1027],{},[260,1014,1015],{},"Netlify",[260,1017,1018,646,1021],{},[456,1019,1020],{},"netlify\u002Ffunctions\u002F",[456,1022,1023],{},"netlify\u002Fedge-functions\u002F",[260,1025,1026],{},"Node or Deno (edge)",[260,1028,1029,1032,1033,1035],{},[456,1030,1031],{},"\u002F.netlify\u002Ffunctions\u002F*"," or ",[456,1034,168],{}," config",[236,1037,1038,1041,1046,1049],{},[260,1039,1040],{},"Vercel",[260,1042,1043],{},[456,1044,1045],{},"api\u002F",[260,1047,1048],{},"Node or Edge",[260,1050,1010],{},[236,1052,1053,1056,1059,1062],{},[260,1054,1055],{},"AWS",[260,1057,1058],{},"separate Lambda \u002F CloudFront Function",[260,1060,1061],{},"Node",[260,1063,1064],{},"CloudFront behaviour or API Gateway",[14,1066,1067],{},"Keeping functions in the site's repository means the form handler and the form markup change in the same pull request, deploy together, and roll back together — the same atomic guarantee static files get. The generator does not matter: an Astro, Hugo or Eleventy build output sits next to the functions directory, and the host wires both up.",[209,1069,1071],{"id":1070},"testing-functions-locally-and-in-ci","Testing Functions Locally and in CI",[14,1073,1074,1075,1078,1079,1082,1083,1086,1087,646,1090,1032,1093,1096],{},"Functions deserve the same test discipline as the rest of the pipeline, and they are easier to test than most server code because each is a single function from request to response. Unit-test the handler by constructing a ",[456,1076,1077],{},"Request"," and asserting on the ",[456,1080,1081],{},"Response","; the Workers runtime, Netlify and Vercel all expose standard Fetch API objects, so tests run in plain Node or in ",[456,1084,1085],{},"vitest"," with the platform's test environment. Run the full local stack with ",[456,1088,1089],{},"wrangler pages dev",[456,1091,1092],{},"netlify dev",[456,1094,1095],{},"vercel dev"," to exercise routing alongside the built site. And add the function routes to the post-deploy smoke tests against every preview: a form endpoint should return 400 on an empty POST and 303 on a valid one, which proves both validation and routing without sending a real message.",[209,1098,1100],{"id":1099},"operating-functions-safely","Operating Functions Safely",[14,1102,1103],{},"Functions are server code, and bring server concerns:",[1105,1106,1107,1118,1124,1130,1140,1146],"ul",{},[1108,1109,1110,1113,1114,1117],"li",{},[219,1111,1112],{},"Secrets"," live in the platform's secret store (",[456,1115,1116],{},"wrangler secret put",", Netlify and Vercel environment variables), never in the repository or the built output.",[1108,1119,1120,1123],{},[219,1121,1122],{},"Rate limits"," on public endpoints: a form or proxy without one is an invitation to abuse. Cloudflare's rate-limiting rules or a counter in KV or Durable Objects cover it.",[1108,1125,1126,1129],{},[219,1127,1128],{},"Input validation"," for every field, with strict length limits and allow-lists rather than trying to block bad input.",[1108,1131,1132,1135,1136,35],{},[219,1133,1134],{},"Observability",": log function errors and latency the same way you monitor the rest of the site, as described in ",[21,1137,1139],{"href":1138},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002F","Monitoring Static Sites in Production",[1108,1141,1142,1145],{},[219,1143,1144],{},"Previews",": functions deploy with every preview, so they must not send real emails or write to production data from preview environments. Gate side effects on an environment variable.",[1108,1147,1148,1151,1152,1155],{},[219,1149,1150],{},"Timeouts to upstreams",": set an explicit timeout on every outbound ",[456,1153,1154],{},"fetch",", and return a graceful fallback, so a slow third party cannot hold a function — and the reader waiting on it — for the platform's maximum duration.",[209,1157,1159],{"id":1158},"cost-model","Cost Model",[14,1161,1162],{},"Function pricing is per request and per unit of compute, which makes it cheap for the traffic static sites actually send to functions — a small fraction of page views. On the site measured below, functions received about 1.4% of all requests: form submissions, the releases widget's cached API calls, and partner-page auth checks. At 1.2 million page views a month that was roughly 17,000 function invocations, well inside the free tiers of every platform listed above. The partner section was the exception, because the auth gate runs on every request to every protected page and asset; its 90,000 monthly requests pushed the site onto a paid Workers plan at 5 USD a month, still less than the VPS it replaced.",[14,1164,1165,1166,1169],{},"Two habits keep costs predictable. Route only the paths that need code through functions — on Cloudflare Pages, ",[456,1167,1168],{},"_routes.json"," excludes static paths from invoking functions at all; on Netlify and Vercel, keep functions under distinct paths rather than catch-all middleware. And cache function responses wherever the data allows, as in the releases proxy above, so repeated requests are answered from cache rather than from compute.",[209,1171,1173],{"id":1172},"measured-impact","Measured Impact",[14,1175,1176],{},"A documentation and marketing site moved four features from third-party embeds and a small VPS to edge functions on Cloudflare: the contact form, a newsletter signup, a GitHub releases widget and a partner-only section.",[230,1178,1179,1192],{},[233,1180,1181],{},[236,1182,1183,1186,1189],{},[239,1184,1185],{},"Measure",[239,1187,1188],{},"Before",[239,1190,1191],{},"After",[255,1193,1194,1204,1215,1226,1237,1247],{},[236,1195,1196,1199,1202],{},[260,1197,1198],{},"Third-party scripts on affected pages",[260,1200,1201],{},"3 (form embed, newsletter widget, GitHub badge)",[260,1203,60],{},[236,1205,1206,1209,1212],{},[260,1207,1208],{},"JavaScript on the contact page (compressed)",[260,1210,1211],{},"142 KB",[260,1213,1214],{},"3 KB",[236,1216,1217,1220,1223],{},[260,1218,1219],{},"Contact page LCP p75 (mobile)",[260,1221,1222],{},"2.9 s",[260,1224,1225],{},"1.4 s",[236,1227,1228,1231,1234],{},[260,1229,1230],{},"Spam submissions per week",[260,1232,1233],{},"~340",[260,1235,1236],{},"~2",[236,1238,1239,1242,1245],{},[260,1240,1241],{},"Servers to patch",[260,1243,1244],{},"1 VPS",[260,1246,60],{},[236,1248,1249,1252,1255],{},[260,1250,1251],{},"Monthly cost",[260,1253,1254],{},"24 USD (VPS + form service)",[260,1256,1257],{},"5 USD (Workers paid plan)",[209,1259,1261],{"id":1260},"common-pitfalls","Common Pitfalls",[1105,1263,1264,1270,1276,1282,1288,1294,1303],{},[1108,1265,1266,1269],{},[219,1267,1268],{},"Functions on the page-load path."," Rendering pages per request discards the CDN cache. Keep pages static; call functions after load or on submit.",[1108,1271,1272,1275],{},[219,1273,1274],{},"Regional functions for global audiences."," A function in one region adds hundreds of milliseconds for distant readers. Prefer edge unless you need regional capabilities.",[1108,1277,1278,1281],{},[219,1279,1280],{},"Secrets in client bundles."," Any key in front-end code is public. Proxy through a function.",[1108,1283,1284,1287],{},[219,1285,1286],{},"No rate limiting."," Public endpoints get abused within days of launch.",[1108,1289,1290,1293],{},[219,1291,1292],{},"Side effects in previews."," Preview deploys run the same functions; stub email and writes outside production.",[1108,1295,1296,1299,1300,1302],{},[219,1297,1298],{},"Caching personalised responses publicly."," Use ",[456,1301,862],{}," or vary the cache key correctly, or one reader's data reaches another.",[1108,1304,1305,1308],{},[219,1306,1307],{},"Catch-all middleware."," A function that runs on every path, including images and scripts, multiplies invocations and adds latency to assets that never needed code. Scope routes narrowly.",[209,1310,1312],{"id":1311},"key-takeaways","Key Takeaways",[1105,1314,1315,1318,1321,1324,1327],{},[1108,1316,1317],{},"Functions add the dynamic 5% a static site needs without giving up static pages or CDN caching.",[1108,1319,1320],{},"Edge functions start in milliseconds and respond in tens of milliseconds worldwide; regional functions are for heavier work.",[1108,1322,1323],{},"Forms, API proxies, auth gates and light personalisation cover almost every static-site use case.",[1108,1325,1326],{},"Keep functions off the page-load path; personalise with islands, edge variants or header injection.",[1108,1328,1329],{},"Treat functions as server code: secrets, rate limits, validation, monitoring and safe previews.",[209,1331,1333],{"id":1332},"faq","FAQ",[1335,1336,1338],"h3",{"id":1337},"does-adding-a-function-make-a-site-no-longer-static","Does adding a function make a site no longer static?",[14,1340,1341],{},"No. The pages stay pre-built files served from the CDN. A function handles only the specific routes that need to run code, such as a form endpoint or an API proxy, so the rest of the site keeps its static performance and simplicity.",[1335,1343,1345],{"id":1344},"edge-functions-or-regional-serverless-functions","Edge functions or regional serverless functions?",[14,1347,1348],{},"Edge functions run in many locations close to readers with fast cold starts and suit short request handling, redirects, headers and lightweight APIs. Regional functions run in one location with fuller Node.js support and longer limits, and suit heavier work or anything that needs a database in the same region.",[1335,1350,1352],{"id":1351},"what-are-the-most-common-uses-on-static-sites","What are the most common uses on static sites?",[14,1354,1355],{},"Contact and signup forms, proxying third-party APIs to hide keys, gating content behind authentication, lightweight personalisation such as geolocation, image or OG generation on demand, and webhooks that trigger rebuilds.",[1335,1357,1359],{"id":1358},"how-do-i-keep-functions-from-slowing-down-pages","How do I keep functions from slowing down pages?",[14,1361,1362],{},"Keep them off the page-load path. Pages should be static and cached; functions should answer separate requests made after load or on form submission. If a function must run on page requests, keep it at the edge and cache its output.",[1335,1364,1366],{"id":1365},"are-functions-a-security-risk-on-a-static-site","Are functions a security risk on a static site?",[14,1368,1369],{},"They add attack surface, so treat them like any server code. Validate input, rate-limit public endpoints, keep secrets in the platform's secret store, and give each function only the permissions it needs.",[209,1371,1373],{"id":1372},"related","Related",[1105,1375,1376,1385,1390,1395,1400,1405,1410,1417,1422,1429,1436],{},[1108,1377,1378,1381,1382,1384],{},[219,1379,1380],{},"Up:"," ",[21,1383,24],{"href":23}," — where functions fit in the deploy pipeline.",[1108,1386,1387,1389],{},[21,1388,466],{"href":465}," — options from hosted services to your own function.",[1108,1391,1392,1394],{},[21,1393,471],{"href":470}," — an end-to-end build.",[1108,1396,1397,1399],{},[21,1398,332],{"href":331}," — choosing a platform.",[1108,1401,1402,1404],{},[21,1403,794],{"href":793}," — hiding keys and caching responses.",[1108,1406,1407,1409],{},[21,1408,805],{"href":804}," — gating static content.",[1108,1411,1412,1416],{},[21,1413,1415],{"href":1414},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fvercel-isr-vs-static-generation-for-ssgs\u002F","Vercel ISR vs Static Generation for SSGs"," — when regeneration beats functions.",[1108,1418,1419,1421],{},[21,1420,962],{"href":961}," — functions that trigger rebuilds.",[1108,1423,1424,1428],{},[21,1425,1427],{"href":1426},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fnewsletter-signup-with-an-edge-function\u002F","Newsletter Signup with an Edge Function"," — replace a newsletter embed on a static site with a native form and a small edge function.",[1108,1430,1431,1435],{},[21,1432,1434],{"href":1433},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Frate-limiting-edge-functions\u002F","Rate Limiting Edge Functions"," — protect the dynamic endpoints of a static site, such as forms and APIs, with edge rate limits.",[1108,1437,1438,1442],{},[21,1439,1441],{"href":1440},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Ffixing-cold-starts-in-netlify-functions-for-forms\u002F","Fixing Cold Starts in Netlify Functions for Forms"," — measure and cut cold-start latency in a Netlify Function behind a static site's form: smaller bundles, lazy imports, regions and honest UI states.",[1444,1445,1446],"style",{},"html pre.shiki code .sJ8bj, html code.shiki .sJ8bj{--shiki-default:#6A737D;--shiki-dark:#6A737D}html pre.shiki code .szBVR, html code.shiki .szBVR{--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s4XuR, html code.shiki .s4XuR{--shiki-default:#E36209;--shiki-dark:#FFAB70}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":486,"searchDepth":499,"depth":499,"links":1448},[1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1461,1462,1469],{"id":211,"depth":499,"text":212},{"id":450,"depth":499,"text":451},{"id":475,"depth":499,"text":476},{"id":797,"depth":499,"text":798},{"id":901,"depth":499,"text":902},{"id":931,"depth":499,"text":932},{"id":969,"depth":499,"text":970},{"id":1070,"depth":499,"text":1071},{"id":1099,"depth":499,"text":1100},{"id":1158,"depth":499,"text":1159},{"id":1172,"depth":499,"text":1173},{"id":1260,"depth":499,"text":1261},{"id":1311,"depth":499,"text":1312},{"id":1332,"depth":499,"text":1333,"children":1463},[1464,1465,1466,1467,1468],{"id":1337,"depth":527,"text":1338},{"id":1344,"depth":527,"text":1345},{"id":1351,"depth":527,"text":1352},{"id":1358,"depth":527,"text":1359},{"id":1365,"depth":527,"text":1366},{"id":1372,"depth":499,"text":1373},[1471,1474,1475],{"name":1472,"item":1473},"Home","\u002F",{"name":24,"item":23},{"name":5,"item":1476},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002F","2026-09-18","Add forms, API proxies, authentication and personalisation to a static site with edge and serverless functions — without giving up static pages or CDN caching.","md",[1481,1482,1483,1484,1485],{"q":1338,"a":1341},{"q":1345,"a":1348},{"q":1352,"a":1355},{"q":1359,"a":1362},{"q":1366,"a":1369},{},true,"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites",{"title":5,"description":1478},"production-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Findex","guide","WHwZYYaztLiGHU0fykuw2Qk-0R_zW3UlUvpLZel20f8",[1494,1497,1500,1503,1506,1509,1512,1515,1518,1521,1524,1527,1530,1533,1536,1539,1542,1545,1548,1551,1554,1557,1560,1563,1566,1569,1572,1575,1578,1581,1584,1587,1590,1593,1596,1599,1602,1605,1608,1611,1614,1617,1620,1623,1626,1629,1632,1635,1638,1641,1644,1647,1650,1653,1656,1659,1662,1665,1668,1671,1674,1677,1680,1683,1686,1689,1692,1695,1698,1701,1704,1707,1710,1713,1716,1719,1722,1725,1728,1731,1734,1737,1740,1743,1746,1749,1752,1755,1758,1761,1764,1767,1770,1773,1776,1779,1782,1785,1788,1791,1794,1797,1800,1803,1806,1809,1812,1815,1818,1821,1824,1827,1830,1833,1836,1839,1842,1845,1848,1851,1854,1857,1860,1863,1866,1869,1872,1875,1878,1881,1884,1887,1890,1893,1896,1899,1902,1905,1908,1911,1914,1917,1920,1923,1926,1929,1932,1935,1938,1941,1944,1947,1950,1953,1956,1959,1962,1965,1968,1971,1974,1977,1980,1983,1986,1989,1992,1995,1998,2001,2004,2007,2010,2013,2016,2019,2022,2025,2028,2031,2034,2037,2040,2043,2046,2049,2052,2055,2058,2061,2064,2067,2070,2073,2076,2079,2082,2085,2088,2091,2094,2097,2100,2103,2106,2109,2112,2115,2118,2121,2124,2127,2130,2133,2136,2139,2142,2145,2148,2151,2154,2157,2160,2163,2166,2169,2172,2175,2178,2181,2184,2187,2190,2193,2196,2199,2202,2205,2208,2211,2214,2217,2220,2223,2226,2229,2232,2235,2238,2241,2244,2247,2250,2253,2256,2259,2262,2264,2267,2270,2273,2276,2279,2282,2285,2288,2291,2294,2297,2299,2302,2305,2308,2311,2314,2317,2320,2323,2326,2329,2332,2335,2338,2341,2344,2347,2350,2353,2356,2359,2362,2365,2368,2371,2374,2377,2380,2383,2385,2388,2391,2394,2397,2400,2403,2406,2409,2412,2415,2418,2421,2423,2425,2428,2431,2434,2437,2439,2442,2445,2448,2451,2454,2457,2460,2463,2466,2469,2472,2475,2478,2481,2484,2487,2490,2493,2496,2499,2502,2505,2508,2511,2514,2517,2520,2523,2526,2529,2532,2535,2538,2541,2544,2547,2550,2553,2556,2559,2562,2565,2568,2571,2574,2577,2580,2583,2585,2587,2589,2590,2592,2594,2596,2598,2600,2603,2606,2609,2612,2615,2618,2621,2624],{"path":1495,"title":1496},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Faccessibility-for-static-sites\u002Faccessible-code-blocks-in-documentation-sites","Accessible Code Blocks in Documentation Sites",{"path":1498,"title":1499},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Faccessibility-for-static-sites\u002Faccessible-dark-mode-toggles-for-static-sites","Accessible Dark Mode Toggles for Static Sites",{"path":1501,"title":1502},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Faccessibility-for-static-sites\u002Faccessible-svg-diagrams-on-static-sites","Accessible SVG Diagrams on Static Sites",{"path":1504,"title":1505},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Faccessibility-for-static-sites\u002Fenforcing-alt-text-for-markdown-images-at-build-time","Enforcing Alt Text for Markdown Images at Build Time",{"path":1507,"title":1508},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Faccessibility-for-static-sites\u002Ffixing-heading-order-problems-in-markdown-content","Fixing Heading Order Problems in Markdown Content",{"path":1510,"title":1511},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Faccessibility-for-static-sites\u002Ffixing-low-color-contrast-flagged-by-lighthouse","Fixing Low Color Contrast Flagged by Lighthouse",{"path":1513,"title":1514},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Faccessibility-for-static-sites","Accessibility for Static Sites",{"path":1516,"title":1517},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Faccessibility-for-static-sites\u002Fkeyboard-navigation-and-focus-order-on-static-sites","Keyboard Navigation and Focus Order on Static Sites",{"path":1519,"title":1520},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Faccessibility-for-static-sites\u002Fskip-links-and-landmarks-in-ssg-layouts","Skip Links and Landmarks in SSG Layouts",{"path":1522,"title":1523},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fastro-vs-eleventy-build-times-at-10000-pages","Astro vs Eleventy Build Times at 10,000 Pages",{"path":1525,"title":1526},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fchoosing-between-astro-and-eleventy-for-large-docs","Astro vs Eleventy for Large Docs (1000+ Pages)",{"path":1528,"title":1529},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fcontent-collections-vs-eleventy-data-cascade","Content Collections vs the Eleventy Data Cascade",{"path":1531,"title":1532},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fdev-server-performance-astro-vs-eleventy","Dev Server Performance: Astro vs Eleventy",{"path":1534,"title":1535},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Ffixing-astro-build-errors-after-upgrading-to-astro-5","Fixing Astro Build Errors After Upgrading to Astro 5",{"path":1537,"title":1538},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Ffixing-duplicate-permalink-errors-in-eleventy","Fixing Duplicate Permalink Errors in Eleventy",{"path":1540,"title":1541},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Ffixing-eleventy-out-of-memory-errors-on-large-collections","Fixing Eleventy Out-of-Memory Errors on Large Collections",{"path":1543,"title":1544},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Ffixing-slow-astro-builds-caused-by-large-mdx-collections","Fixing Slow Astro Builds Caused by Large MDX Collections",{"path":1546,"title":1547},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites","Astro vs Eleventy for Documentation Sites",{"path":1549,"title":1550},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Floading-remote-content-with-astro-content-layer-loaders","Loading Remote Content With Astro Content Layer Loaders",{"path":1552,"title":1553},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fmarkdown-pipelines-remark-vs-markdown-it","Markdown Pipelines: remark vs markdown-it",{"path":1555,"title":1556},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fshortcodes-vs-components-for-docs-authors","Shortcodes vs Components for Docs Authors",{"path":1558,"title":1559},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fsidebar-navigation-in-astro-and-eleventy","Sidebar Navigation in Astro and Eleventy",{"path":1561,"title":1562},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fsyntax-highlighting-with-shiki-in-astro-and-eleventy","Syntax Highlighting with Shiki in Astro and Eleventy",{"path":1564,"title":1565},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites\u002Fupgrading-eleventy-2-to-3-with-esm-configuration","Upgrading Eleventy 2 to 3 With ESM Configuration",{"path":1567,"title":1568},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fadding-local-search-to-a-vitepress-site","Adding Local Search to a VitePress Site",{"path":1570,"title":1571},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fcomparing-docs-framework-build-times","Comparing Docs Framework Build Times",{"path":1573,"title":1574},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fcustomizing-starlight-without-forking-the-theme","Customizing Starlight Without Forking the Theme",{"path":1576,"title":1577},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fdocusaurus-vs-starlight-for-product-documentation","Docusaurus vs Starlight for Product Documentation",{"path":1579,"title":1580},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Ffixing-broken-links-reported-by-docusaurus-builds","Fixing Broken Links Reported by Docusaurus Builds",{"path":1582,"title":1583},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fgenerating-api-reference-pages-in-starlight-from-openapi","Generating API Reference Pages in Starlight From OpenAPI",{"path":1585,"title":1586},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress","Docs Frameworks: Docusaurus, Starlight and VitePress",{"path":1588,"title":1589},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Finternationalizing-starlight-docs","Internationalizing Starlight Docs",{"path":1591,"title":1592},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fmdx-vs-markdoc-for-docs-content","MDX vs Markdoc for Docs Content",{"path":1594,"title":1595},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fmigrating-from-mkdocs-to-starlight","Migrating from MkDocs to Starlight",{"path":1597,"title":1598},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fmigrating-mkdocs-documentation-to-vitepress","Migrating MkDocs Documentation to VitePress",{"path":1600,"title":1601},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fspeeding-up-docusaurus-builds-with-rspack","Speeding Up Docusaurus Builds With Rspack",{"path":1603,"title":1604},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fversioned-documentation-with-docusaurus","Versioned Documentation with Docusaurus",{"path":1606,"title":1607},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fversioning-vitepress-documentation-without-a-plugin","Versioning VitePress Documentation Without a Plugin",{"path":1609,"title":1610},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fvitepress-for-library-documentation","VitePress for Library Documentation",{"path":1612,"title":1613},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fvitepress-vs-starlight-for-vue-and-astro-teams","VitePress vs Starlight for Vue and Astro Teams",{"path":1615,"title":1616},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Ffixing-hugo-builds-that-fail-after-a-version-upgrade","Fixing Hugo Builds That Fail After a Version Upgrade",{"path":1618,"title":1619},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Ffixing-hugo-builds-that-slow-down-after-adding-taxonomies","Fixing Hugo Builds That Slow Down After Adding Taxonomies",{"path":1621,"title":1622},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fhow-to-benchmark-hugo-vs-astro-build-speeds","How to Benchmark Hugo vs Astro Build Speeds",{"path":1624,"title":1625},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fhugo-image-processing-cache-in-ci","Hugo Image Processing Cache in CI",{"path":1627,"title":1628},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fhugo-modules-and-dependency-caching","Hugo Modules and Dependency Caching",{"path":1630,"title":1631},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fhugo-partialcached-for-faster-builds","Hugo partialCached for Faster Builds",{"path":1633,"title":1634},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories","Hugo Build Times for Large Repositories",{"path":1636,"title":1637},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fparallel-hugo-builds-across-ci-jobs","Parallel Hugo Builds Across CI Jobs",{"path":1639,"title":1640},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fprofiling-hugo-templates-with-template-metrics","Profiling Hugo Templates With Template Metrics",{"path":1642,"title":1643},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Freducing-hugo-memory-usage-on-ci-runners","Reducing Hugo Memory Usage on CI Runners",{"path":1645,"title":1646},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fsharing-a-theme-across-hugo-sites-with-modules","Sharing a Theme Across Hugo Sites With Modules",{"path":1648,"title":1649},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fspeeding-up-hugo-builds-with-render-hooks-and-caching","Speeding Up Hugo Builds with Render Hooks & Caching",{"path":1651,"title":1652},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories\u002Fsplitting-large-hugo-sites-with-segments","Splitting Large Hugo Sites with Segments",{"path":1654,"title":1655},"\u002Fchoosing-the-right-static-site-generator-for-production","Choosing the Right Static Site Generator for Production",{"path":1657,"title":1658},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites\u002Ffixing-hreflang-errors-reported-in-search-console","Fixing Hreflang Errors Reported in Search Console",{"path":1660,"title":1661},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites\u002Fhreflang-and-language-alternates-on-static-sites","hreflang and Language Alternates on Static Sites",{"path":1663,"title":1664},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites\u002Fi18n-routing-in-astro","i18n Routing in Astro",{"path":1666,"title":1667},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites","Internationalization for Static Sites",{"path":1669,"title":1670},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites\u002Flanguage-detection-and-redirects-at-the-edge","Language Detection and Redirects at the Edge",{"path":1672,"title":1673},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites\u002Fmultilingual-eleventy-sites-with-the-i18n-plugin","Multilingual Eleventy Sites With the i18n Plugin",{"path":1675,"title":1676},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites\u002Fmultilingual-sites-with-hugo","Multilingual Sites with Hugo",{"path":1678,"title":1679},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites\u002Fright-to-left-layouts-on-static-sites","Right-to-Left Layouts on Static Sites",{"path":1681,"title":1682},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites\u002Fsubdirectories-vs-subdomains-for-translated-static-sites","Subdirectories vs Subdomains for Translated Static Sites",{"path":1684,"title":1685},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites\u002Ftranslation-workflows-with-git-and-crowdin","Translation Workflows with Git and Crowdin",{"path":1687,"title":1688},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fcustom-domains-and-https-for-jekyll-on-github-pages","Custom Domains and HTTPS for Jekyll on GitHub Pages",{"path":1690,"title":1691},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fdeploying-jekyll-with-github-actions","Deploying Jekyll with GitHub Actions",{"path":1693,"title":1694},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Feleventy-vs-jekyll-for-markdown-heavy-blogs","Eleventy vs Jekyll for Markdown-Heavy Blogs",{"path":1696,"title":1697},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Ffixing-jekyll-builds-that-break-after-a-ruby-upgrade","Fixing Jekyll Builds That Break After a Ruby Upgrade",{"path":1699,"title":1700},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem","Jekyll Plugin Ecosystem",{"path":1702,"title":1703},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Freplacing-jekyll-plugins-when-migrating-to-eleventy","Replacing Jekyll Plugins When Migrating to Eleventy",{"path":1705,"title":1706},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Frunning-jekyll-in-docker-for-reproducible-builds","Running Jekyll in Docker for Reproducible Builds",{"path":1708,"title":1709},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Frunning-jekyll-on-github-pages-without-plugins","Running Jekyll on GitHub Pages Without Plugins",{"path":1711,"title":1712},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fspeeding-up-slow-jekyll-builds","Speeding Up Slow Jekyll Builds",{"path":1714,"title":1715},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fupgrading-jekyll-and-ruby-versions-safely","Upgrading Jekyll and Ruby Versions Safely",{"path":1717,"title":1718},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fauditing-content-parity-after-a-migration","Auditing Content Parity After a Migration",{"path":1720,"title":1721},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fconverting-front-matter-at-scale-during-migration","Converting Front Matter at Scale During Migration",{"path":1723,"title":1724},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators","Migrating Between Static Site Generators",{"path":1726,"title":1727},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fkeeping-redirects-working-after-an-ssg-migration","Keeping Redirects Working After an SSG Migration",{"path":1729,"title":1730},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-a-docs-site-from-jekyll-to-hugo","Migrating a Docs Site From Jekyll to Hugo",{"path":1732,"title":1733},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-a-wordpress-export-to-eleventy","Migrating a WordPress Export to Eleventy",{"path":1735,"title":1736},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-from-docusaurus-to-starlight","Migrating from Docusaurus to Starlight",{"path":1738,"title":1739},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-from-gatsby-to-astro","Migrating from Gatsby to Astro",{"path":1741,"title":1742},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-from-hugo-to-astro-without-breaking-urls","Migrating From Hugo to Astro Without Breaking URLs",{"path":1744,"title":1745},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-from-nextjs-pages-router-to-astro","Migrating from Next.js Pages Router to Astro",{"path":1747,"title":1748},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-wordpress-to-a-static-site-generator","Migrating WordPress to a Static Site Generator",{"path":1750,"title":1751},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fporting-shortcodes-and-includes-between-generators","Porting Shortcodes and Includes Between Generators",{"path":1753,"title":1754},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Frecovering-search-traffic-lost-after-a-generator-migration","Recovering Search Traffic Lost After a Generator Migration",{"path":1756,"title":1757},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Freplacing-gatsby-graphql-queries-during-a-migration","Replacing Gatsby GraphQL Queries During a Migration",{"path":1759,"title":1760},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Ffixing-404s-on-refresh-in-nextjs-static-export","Fixing 404s on Refresh in Next.js Static Export",{"path":1762,"title":1763},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fgenerating-sitemaps-and-rss-in-nextjs-static-export","Generating Sitemaps and RSS in Next.js Static Export",{"path":1765,"title":1766},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fhandling-dynamic-routes-in-nextjs-static-export","Handling Dynamic Routes in Next.js Static Export",{"path":1768,"title":1769},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites","Next.js Static Export for Content Sites",{"path":1771,"title":1772},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fmigrating-from-gatsby-to-nextjs-static-export","Migrating from Gatsby to Next.js Static Export",{"path":1774,"title":1775},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fnextjs-app-router-static-export-limitations","Next.js App Router Static Export Limitations",{"path":1777,"title":1778},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fnextjs-static-export-vs-astro-for-marketing-sites","Next.js Static Export vs Astro for Marketing",{"path":1780,"title":1781},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fnextjs-static-export-vs-gatsby-for-existing-react-sites","Next.js Static Export vs Gatsby for Existing React Sites",{"path":1783,"title":1784},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Foptimizing-images-in-nextjs-static-export","Optimizing Images in Next.js Static Export",{"path":1786,"title":1787},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Ftrailing-slash-and-basepath-in-nextjs-static-export","Trailing Slash and basePath in Next.js Static Export",{"path":1789,"title":1790},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Fusing-mdx-in-nextjs-static-export","Using MDX in Next.js Static Export",{"path":1792,"title":1793},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Faccessible-search-ui-for-static-sites","Accessible Search UI for Static Sites",{"path":1795,"title":1796},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fadding-pagefind-to-an-astro-site","Adding Pagefind to an Astro Site",{"path":1798,"title":1799},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fbuilding-a-lunr-index-at-build-time-in-eleventy","Building a Lunr Index at Build Time in Eleventy",{"path":1801,"title":1802},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fcustomizing-the-pagefind-ui","Customizing the Pagefind UI",{"path":1804,"title":1805},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Ffixing-missing-results-in-pagefind-indexes","Fixing Missing Results in Pagefind Indexes",{"path":1807,"title":1808},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites","Search for Static Sites",{"path":1810,"title":1811},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Findexing-hugo-sites-with-pagefind","Indexing Hugo Sites with Pagefind",{"path":1813,"title":1814},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fmultilingual-search-on-static-sites","Multilingual Search on Static Sites",{"path":1816,"title":1817},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fpagefind-vs-algolia-docsearch","Pagefind vs Algolia DocSearch",{"path":1819,"title":1820},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fpagefind-vs-lunr-for-small-documentation-sites","Pagefind vs Lunr for Small Documentation Sites",{"path":1822,"title":1823},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fsearch-index-size-budgets-for-large-docs","Search Index Size Budgets for Large Docs",{"path":1825,"title":1826},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fself-hosting-typesense-for-a-static-site","Self-Hosting Typesense for a Static Site",{"path":1828,"title":1829},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Ftracking-zero-result-searches","Tracking Zero-Result Searches",{"path":1831,"title":1832},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fbest-ssg-for-technical-writers-without-coding-experience","Best SSG for Non-Developer Technical Writers",{"path":1834,"title":1835},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fchoosing-an-ssg-for-a-marketing-site-with-non-technical-editors","Choosing an SSG for a Marketing Site with Non-Technical Editors",{"path":1837,"title":1838},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fchoosing-an-ssg-for-api-reference-documentation","Choosing an SSG for API Reference Documentation",{"path":1840,"title":1841},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fevaluating-ssg-accessibility-defaults","Evaluating SSG Accessibility Defaults",{"path":1843,"title":1844},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fgatsby-vs-astro-for-content-sites-in-2026","Gatsby vs Astro for Content Sites in 2026",{"path":1846,"title":1847},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix","SSG Framework Selection Matrix",{"path":1849,"title":1850},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fpicking-an-ssg-for-a-multi-language-documentation-site","Picking an SSG for a Multi-Language Docs Site",{"path":1852,"title":1853},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fscoring-ssg-long-term-maintenance-risk","Scoring SSG Long-Term Maintenance Risk",{"path":1855,"title":1856},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fssg-selection-checklist-for-engineering-teams","SSG Selection Checklist for Engineering Teams",{"path":1858,"title":1859},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Ftotal-cost-of-ownership-for-static-site-generators","Total Cost of Ownership for Static Site Generators",{"path":1861,"title":1862},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fwhen-a-static-site-generator-is-the-wrong-choice","When a Static Site Generator Is the Wrong Choice",{"path":1864,"title":1865},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Ftechnical-seo-for-static-sites\u002Fadding-json-ld-structured-data-at-build-time","Adding JSON-LD Structured Data at Build Time",{"path":1867,"title":1868},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Ftechnical-seo-for-static-sites\u002Fcanonical-urls-and-duplicate-content-on-static-sites","Canonical URLs and Duplicate Content on Static Sites",{"path":1870,"title":1871},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Ftechnical-seo-for-static-sites\u002Ffixing-pages-crawled-but-not-indexed-on-static-sites","Fixing Pages Crawled but Not Indexed on Static Sites",{"path":1873,"title":1874},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Ftechnical-seo-for-static-sites\u002Ffixing-soft-404s-on-static-hosts","Fixing Soft 404s on Static Hosts",{"path":1876,"title":1877},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Ftechnical-seo-for-static-sites\u002Fgenerating-breadcrumb-structured-data-in-astro","Generating Breadcrumb Structured Data in Astro",{"path":1879,"title":1880},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Ftechnical-seo-for-static-sites\u002Fgenerating-sitemaps-for-large-static-sites","Generating Sitemaps for Large Static Sites",{"path":1882,"title":1883},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Ftechnical-seo-for-static-sites","Technical SEO for Static Sites",{"path":1885,"title":1886},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Ftechnical-seo-for-static-sites\u002Frobots-txt-and-noindex-for-preview-and-staging","robots.txt and noindex for Preview and Staging",{"path":1888,"title":1889},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Ftechnical-seo-for-static-sites\u002Frss-and-atom-feeds-for-static-blogs","RSS and Atom Feeds for Static Blogs",{"path":1891,"title":1892},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Ftechnical-seo-for-static-sites\u002Fseo-safe-pagination-and-tag-pages","SEO-Safe Pagination and Tag Pages",{"path":1894,"title":1895},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fcache-busting-with-content-hashed-filenames","Cache Busting with Content-Hashed Filenames",{"path":1897,"title":1898},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fcache-control-headers-for-static-sites-in-nginx","Cache-Control Headers for Static Sites in Nginx",{"path":1900,"title":1901},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fcache-control-headers-on-s3-and-cloudfront","Cache-Control Headers on S3 and CloudFront",{"path":1903,"title":1904},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fcache-control-headers-on-vercel-for-static-sites","Cache-Control Headers on Vercel for Static Sites",{"path":1906,"title":1907},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fcache-keys-and-query-strings-on-cdns","Cache Keys and Query Strings on CDNs",{"path":1909,"title":1910},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fcaching-404s-and-redirects-at-the-edge","Caching 404s and Redirects at the Edge",{"path":1912,"title":1913},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fcloudflare-vs-cloudfront-cache-hit-ratios-for-static-sites","Cloudflare vs CloudFront Cache Hit Ratios for Static Sites",{"path":1915,"title":1916},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Ffixing-stale-html-after-deploys-on-cloudflare","Fixing Stale HTML After Deploys on Cloudflare",{"path":1918,"title":1919},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs","CDN Caching Rules for SSGs",{"path":1921,"title":1922},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fpurging-the-cdn-cache-after-a-static-deploy","Purging the CDN Cache After a Static Deploy",{"path":1924,"title":1925},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fsetting-cache-control-headers-on-cloudflare-pages","Cache-Control Headers on Cloudflare Pages",{"path":1927,"title":1928},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fsetting-up-proper-cache-headers-on-netlify","Proper Cache Headers on Netlify for SSGs",{"path":1930,"title":1931},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fstale-while-revalidate-for-static-html","Stale-While-Revalidate for Static HTML",{"path":1933,"title":1934},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Ftiered-caching-and-origin-shield","Tiered Caching and Origin Shield",{"path":1936,"title":1937},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcss-and-javascript-asset-optimization\u002Fcode-splitting-and-module-preload-in-vite-based-ssgs","Code Splitting and Module Preload in Vite-Based SSGs",{"path":1939,"title":1940},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcss-and-javascript-asset-optimization\u002Ffixing-missing-tailwind-classes-in-production-builds","Fixing Missing Tailwind Classes in Production Builds",{"path":1942,"title":1943},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcss-and-javascript-asset-optimization\u002Ffixing-unused-javascript-warnings-on-static-pages","Fixing Unused JavaScript Warnings on Static Pages",{"path":1945,"title":1946},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcss-and-javascript-asset-optimization","CSS and JavaScript Asset Optimization",{"path":1948,"title":1949},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcss-and-javascript-asset-optimization\u002Finlining-critical-css-on-static-sites","Inlining Critical CSS on Static Sites",{"path":1951,"title":1952},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcss-and-javascript-asset-optimization\u002Fkeeping-tailwind-css-output-small-on-static-sites","Keeping Tailwind CSS Output Small on Static Sites",{"path":1954,"title":1955},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcss-and-javascript-asset-optimization\u002Fminifying-html-css-and-js-in-eleventy","Minifying HTML, CSS and JS in Eleventy",{"path":1957,"title":1958},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcss-and-javascript-asset-optimization\u002Fprecompressing-assets-with-brotli-and-zstd","Precompressing Assets with Brotli and Zstd",{"path":1960,"title":1961},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcss-and-javascript-asset-optimization\u002Fpurging-unused-css-with-tailwind-and-lightningcss","Purging Unused CSS with Tailwind and Lightning CSS",{"path":1963,"title":1964},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcss-and-javascript-asset-optimization\u002Fsvg-icon-sprites-vs-inline-icons","SVG Icon Sprites vs Inline Icons",{"path":1966,"title":1967},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcss-and-javascript-asset-optimization\u002Ftailwind-v4-in-astro-without-postcss-plugins","Tailwind v4 in Astro Without PostCSS Plugins",{"path":1969,"title":1970},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Fcls-from-client-side-rendered-components","CLS from Client-Side Rendered Components",{"path":1972,"title":1973},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Fdebugging-cls-with-the-layout-instability-api","Debugging CLS with the Layout Instability API",{"path":1975,"title":1976},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Feliminating-layout-shift-from-web-fonts","Eliminating Layout Shift From Web Fonts",{"path":1978,"title":1979},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Ffixing-cls-from-cookie-banners","Fixing CLS from Cookie Banners",{"path":1981,"title":1982},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Ffixing-cls-from-dynamic-table-of-contents-widgets","Fixing CLS From Dynamic Table of Contents Widgets",{"path":1984,"title":1985},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Ffixing-cls-from-images-without-dimensions-in-markdown","Fixing CLS From Images Without Dimensions in Markdown",{"path":1987,"title":1988},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Ffixing-cls-from-late-loading-embeds","Fixing CLS From Late-Loading Embeds",{"path":1990,"title":1991},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Ffixing-cls-from-sticky-headers-and-anchor-links","Fixing CLS from Sticky Headers and Anchor Links",{"path":1993,"title":1994},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites","Cumulative Layout Shift Fixes for Static Sites",{"path":1996,"title":1997},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Fmeasuring-cls-in-the-field-with-web-vitals-js","Measuring CLS in the Field With web-vitals.js",{"path":1999,"title":2000},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Freserving-space-for-ad-and-promo-slots","Reserving Space for Ad and Promo Slots",{"path":2002,"title":2003},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites\u002Freserving-space-for-images-and-embeds-to-stop-layout-shift","Reserving Space for Images and Embeds",{"path":2005,"title":2006},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fauditing-font-payload-per-page","Auditing Font Payload per Page",{"path":2008,"title":2009},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Ffixing-invisible-text-while-web-fonts-load","Fixing Invisible Text While Web Fonts Load",{"path":2011,"title":2012},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Ffont-display-optional-vs-swap","font-display: optional vs swap",{"path":2014,"title":2015},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites","Font Loading Strategies for Static Sites",{"path":2017,"title":2018},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fmetric-matched-fallback-fonts-with-size-adjust","Metric-Matched Fallback Fonts with size-adjust",{"path":2020,"title":2021},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fpreloading-fonts-without-double-downloads","Preloading Fonts Without Double Downloads",{"path":2023,"title":2024},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fself-hosted-fonts-vs-google-fonts-for-static-sites","Self-Hosted Fonts vs Google Fonts for Static Sites",{"path":2026,"title":2027},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fself-hosting-google-fonts-to-eliminate-layout-shift","Self-Host Google Fonts to Eliminate Layout Shift",{"path":2029,"title":2030},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fsubsetting-variable-fonts-for-faster-first-render","Subsetting Variable Fonts for Faster First Render",{"path":2032,"title":2033},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fusing-system-font-stacks-to-skip-webfonts","Using System Font Stacks to Skip Web Fonts",{"path":2035,"title":2036},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fvariable-fonts-vs-static-weights","Variable Fonts vs Static Weights",{"path":2038,"title":2039},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fart-direction-with-the-picture-element","Art Direction with the Picture Element",{"path":2041,"title":2042},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fblur-up-placeholders-with-lqip","Blur-Up Placeholders with LQIP",{"path":2044,"title":2045},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fbuilding-an-image-cdn-pipeline-for-static-sites","Building an Image CDN Pipeline for Static Sites",{"path":2047,"title":2048},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fcaching-processed-images-between-builds","Caching Processed Images Between Builds",{"path":2050,"title":2051},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Ffixing-blurry-images-from-astro-assets-resizing","Fixing Blurry Images From astro:assets Resizing",{"path":2053,"title":2054},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fgenerating-open-graph-images-at-build-time","Generating Open Graph Images at Build Time",{"path":2056,"title":2057},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro","Image Optimization Pipelines in Astro",{"path":2059,"title":2060},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Flazy-loading-images-without-hurting-lcp","Lazy-Loading Images Without Hurting LCP",{"path":2062,"title":2063},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Foptimizing-webp-images-in-hugo-without-plugins","Optimizing WebP Images in Hugo Without Plugins",{"path":2065,"title":2066},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fresponsive-images-with-srcset-in-eleventy","Responsive Images with srcset in Eleventy",{"path":2068,"title":2069},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fserving-astro-images-through-cloudflare-image-resizing","Serving Astro Images Through Cloudflare Image Resizing",{"path":2071,"title":2072},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fserving-avif-with-fallbacks-on-static-sites","Serving AVIF With Fallbacks on Static Sites",{"path":2074,"title":2075},"\u002Fperformance-optimization-core-web-vitals-for-ssgs","Core Web Vitals Optimization for SSGs",{"path":2077,"title":2078},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fastro-islands-vs-full-hydration-performance","Astro Islands vs Full Hydration Performance",{"path":2080,"title":2081},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fbreaking-up-long-tasks-on-static-sites","Breaking Up Long Tasks on Static Sites",{"path":2083,"title":2084},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fdeferring-hydration-with-client-visible-in-astro","Deferring Hydration with client:visible in Astro",{"path":2086,"title":2087},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Ffixing-hydration-mismatch-errors-in-astro-islands","Fixing Hydration Mismatch Errors in Astro Islands",{"path":2089,"title":2090},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Ffixing-poor-inp-on-static-pages-with-heavy-widgets","Fixing Poor INP on Static Pages With Heavy Widgets",{"path":2092,"title":2093},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fhow-to-reduce-bundle-size-in-eleventy-builds","How to Reduce Bundle Size in Eleventy Builds",{"path":2095,"title":2096},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering","JavaScript Hydration & Partial Rendering",{"path":2098,"title":2099},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fmeasuring-inp-on-static-sites-with-real-user-monitoring","Measuring INP on Static Sites with RUM",{"path":2101,"title":2102},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fpreact-vs-react-islands-bundle-size","Preact vs React Islands Bundle Size",{"path":2104,"title":2105},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Freplacing-react-islands-with-web-components","Replacing React Islands with Web Components",{"path":2107,"title":2108},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fserver-islands-in-astro","Server Islands in Astro",{"path":2110,"title":2111},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Feliminating-render-blocking-css-on-static-sites","Eliminating Render-Blocking CSS on Static Sites",{"path":2113,"title":2114},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Ffixing-lcp-on-text-heavy-documentation-pages","Fixing LCP on Text-Heavy Documentation Pages",{"path":2116,"title":2117},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Ffixing-lcp-regressions-caused-by-cookie-consent-tools","Fixing LCP Regressions Caused by Cookie Consent Tools",{"path":2119,"title":2120},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Ffixing-lcp-when-the-hero-is-a-background-image","Fixing LCP When the Hero Is a Background Image",{"path":2122,"title":2123},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Ffixing-slow-lcp-on-pages-with-embedded-video","Fixing Slow LCP on Pages With Embedded Video",{"path":2125,"title":2126},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Fimproving-ttfb-for-static-html","Improving TTFB for Static HTML",{"path":2128,"title":2129},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites","Largest Contentful Paint Optimization for Static Sites",{"path":2131,"title":2132},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Fmeasuring-lcp-subparts-with-devtools","Measuring LCP Subparts with DevTools",{"path":2134,"title":2135},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Foptimizing-lcp-on-astro-with-priority-hints","Optimizing LCP on Astro with Priority Hints",{"path":2137,"title":2138},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites\u002Freducing-lcp-from-hero-images-on-static-sites","Reducing LCP from Hero Images on Static Sites",{"path":2140,"title":2141},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fcomparing-lab-and-field-data-with-crux","Comparing Lab and Field Data with CrUX",{"path":2143,"title":2144},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci","Performance Budgets and Lighthouse CI",{"path":2146,"title":2147},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Flighthouse-ci-vs-webpagetest-for-regression-gates","Lighthouse CI vs WebPageTest for Regression Gates",{"path":2149,"title":2150},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fmeasuring-web-vitals-in-playwright-tests","Measuring Web Vitals in Playwright Tests",{"path":2152,"title":2153},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fper-template-performance-budgets","Per-Template Performance Budgets",{"path":2155,"title":2156},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fperformance-testing-on-throttled-mobile-profiles","Performance Testing on Throttled Mobile Profiles",{"path":2158,"title":2159},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Freducing-lighthouse-score-variance-in-ci","Reducing Lighthouse Score Variance in CI",{"path":2161,"title":2162},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Frunning-webpagetest-scripts-against-preview-deploys","Running WebPageTest Scripts Against Preview Deploys",{"path":2164,"title":2165},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fsetting-up-lighthouse-ci-for-a-static-site","Setting Up Lighthouse CI for a Static Site",{"path":2167,"title":2168},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Ftracking-bundle-size-per-pull-request","Tracking Bundle Size per Pull Request",{"path":2170,"title":2171},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Ftracking-page-weight-over-time","Tracking Page Weight Over Time",{"path":2173,"title":2174},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fwriting-a-performance-budget-that-fails-builds","Writing a Performance Budget That Fails Builds",{"path":2176,"title":2177},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fauditing-unused-preloads","Auditing Unused Preloads",{"path":2179,"title":2180},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fearly-hints-103-on-cloudflare","Early Hints (103) on Cloudflare",{"path":2182,"title":2183},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Ffetchpriority-beyond-the-hero-image","Fetchpriority Beyond the Hero Image",{"path":2185,"title":2186},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Ffixing-wasted-preloads-flagged-by-chrome","Fixing Wasted Preloads Flagged by Chrome",{"path":2188,"title":2189},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed","Resource Hints and Navigation Speed",{"path":2191,"title":2192},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Finstant-navigation-with-speculation-rules","Instant Navigation with Speculation Rules",{"path":2194,"title":2195},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fpreconnect-vs-dns-prefetch-on-static-sites","Preconnect vs DNS-Prefetch on Static Sites",{"path":2197,"title":2198},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fprefetching-links-in-astro","Prefetching Links in Astro",{"path":2200,"title":2201},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fview-transitions-in-astro-without-hurting-vitals","View Transitions in Astro Without Hurting Vitals",{"path":2203,"title":2204},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fview-transitions-on-multi-page-static-sites","View Transitions on Multi-Page Static Sites",{"path":2206,"title":2207},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Fauditing-third-party-scripts-with-lighthouse","Auditing Third-Party Scripts With Lighthouse",{"path":2209,"title":2210},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Ffacades-for-chat-widgets-and-maps","Facades for Chat Widgets and Maps",{"path":2212,"title":2213},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Ffixing-main-thread-blocking-from-chat-widgets","Fixing Main-Thread Blocking From Chat Widgets",{"path":2215,"title":2216},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites","Third-Party Script Performance on Static Sites",{"path":2218,"title":2219},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Flazy-loading-youtube-embeds-on-static-sites","Lazy-Loading YouTube Embeds on Static Sites",{"path":2221,"title":2222},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Floading-google-tag-manager-without-hurting-inp","Loading Google Tag Manager Without Hurting INP",{"path":2224,"title":2225},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Fmeasuring-third-party-cost-with-request-blocking","Measuring Third-Party Cost with Request Blocking",{"path":2227,"title":2228},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Fprivacy-friendly-analytics-compared-by-page-weight","Privacy-Friendly Analytics Compared by Page Weight",{"path":2230,"title":2231},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Frunning-third-party-scripts-in-a-web-worker-with-partytown","Running Third-Party Scripts in a Web Worker with Partytown",{"path":2233,"title":2234},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites\u002Fself-hosting-analytics-to-cut-third-party-requests","Self-Hosting Analytics to Cut Third-Party Requests",{"path":2236,"title":2237},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fautomating-eleventy-deployments-with-cloudflare-pages","Automating Eleventy Deployments on Cloudflare Pages",{"path":2239,"title":2240},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fbranch-deploy-controls-on-cloudflare-pages","Branch Deploy Controls on Cloudflare Pages",{"path":2242,"title":2243},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fcloudflare-pages-functions-middleware","Cloudflare Pages Functions Middleware",{"path":2245,"title":2246},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fconfiguring-redirects-on-cloudflare-pages","Configuring Redirects on Cloudflare Pages",{"path":2248,"title":2249},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fcustom-domains-and-tls-on-cloudflare-pages","Custom Domains and TLS on Cloudflare Pages",{"path":2251,"title":2252},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fdeploying-astro-to-cloudflare-workers-static-assets","Deploying Astro to Cloudflare Workers Static Assets",{"path":2254,"title":2255},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fdeploying-hugo-to-cloudflare-pages-and-workers","Deploying Hugo to Cloudflare Pages and Workers",{"path":2257,"title":2258},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fdeploying-to-cloudflare-from-github-actions-with-wrangler","Deploying to Cloudflare From GitHub Actions With Wrangler",{"path":2260,"title":2261},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Ffixing-redirect-loops-on-cloudflare-pages","Fixing Redirect Loops on Cloudflare Pages",{"path":2263,"title":34},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup",{"path":2265,"title":2266},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fmigrating-from-cloudflare-pages-to-workers-static-assets","Migrating from Cloudflare Pages to Workers Static Assets",{"path":2268,"title":2269},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fchecking-links-in-pull-requests","Checking Links in Pull Requests",{"path":2271,"title":2272},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fcontent-linting-with-markdownlint","Content Linting with markdownlint",{"path":2274,"title":2275},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fdocs-as-code-review-workflow-for-writers","Docs-as-Code Review Workflow for Writers",{"path":2277,"title":2278},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Feditorial-checks-with-vale-in-ci","Editorial Checks with Vale in CI",{"path":2280,"title":2281},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fgit-based-cms-options-for-static-sites-compared","Git-Based CMS Options for Static Sites Compared",{"path":2283,"title":2284},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams","Content Workflows for Documentation Teams",{"path":2286,"title":2287},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fmanaging-images-in-docs-as-code-repos","Managing Images in Docs-as-Code Repos",{"path":2289,"title":2290},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Frelease-notes-and-changelogs-from-git","Release Notes and Changelogs from Git",{"path":2292,"title":2293},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fscheduled-content-publishing-with-github-actions","Scheduled Content Publishing With GitHub Actions",{"path":2295,"title":2296},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fscheduling-content-publication-with-cron-triggered-builds","Scheduling Content Publication With Cron-Triggered Builds",{"path":2298,"title":966},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fwiring-a-headless-cms-to-a-static-build",{"path":2300,"title":2301},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fbuilding-astro-sites-with-github-actions","Building Astro Sites with GitHub Actions",{"path":2303,"title":2304},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fcaching-node-modules-in-github-actions-for-faster-ssg-builds","Caching node_modules in GitHub Actions",{"path":2306,"title":2307},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fconcurrency-groups-to-cancel-stale-builds","Concurrency Groups to Cancel Stale Builds",{"path":2309,"title":2310},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fdeploying-to-github-pages-with-actions","Deploying to GitHub Pages with Actions",{"path":2312,"title":2313},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fdeploying-to-multiple-environments-from-one-workflow","Deploying to Multiple Environments From One Workflow",{"path":2315,"title":2316},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Ffixing-flaky-static-site-builds-in-github-actions","Fixing Flaky Static Site Builds in GitHub Actions",{"path":2318,"title":2319},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fhow-to-set-up-github-actions-for-hugo-deployments","GitHub Actions for Hugo Deployments",{"path":2321,"title":2322},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds","GitHub Actions for Automated SSG Builds",{"path":2324,"title":2325},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fmatrix-builds-for-multi-site-monorepos","Matrix Builds for Multi-Site Monorepos",{"path":2327,"title":2328},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fpinning-actions-by-commit-sha","Pinning Actions by Commit SHA",{"path":2330,"title":2331},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fpublishing-any-generator-to-github-pages-with-actions","Publishing Any Generator to GitHub Pages With Actions",{"path":2333,"title":2334},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Freusable-workflows-for-ssg-builds","Reusable Workflows for SSG Builds",{"path":2336,"title":2337},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fbuild-caching-on-netlify-and-vercel","Build Caching on Netlify and Vercel",{"path":2339,"title":2340},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fcaching-hugo-builds-in-github-actions","Caching Hugo Builds in GitHub Actions",{"path":2342,"title":2343},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fdeploying-only-changed-files","Deploying Only Changed Files",{"path":2345,"title":2346},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fenabling-incremental-builds-in-eleventy","Enabling Incremental Builds in Eleventy",{"path":2348,"title":2349},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Ffixing-stale-pages-from-incremental-builds","Fixing Stale Pages From Incremental Builds",{"path":2351,"title":2352},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fincremental-builds-in-astro-with-the-content-layer","Incremental Builds in Astro with the Content Layer",{"path":2354,"title":2355},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fincremental-rebuild-times-across-astro-eleventy-and-hugo","Incremental Rebuild Times Across Astro, Eleventy and Hugo",{"path":2357,"title":2358},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs","Incremental Builds and Build Caching for SSGs",{"path":2360,"title":2361},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fmeasuring-build-time-regressions-in-ci","Measuring Build-Time Regressions in CI",{"path":2363,"title":2364},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fremote-caching-with-turborepo-for-ssg-monorepos","Remote Caching with Turborepo for SSG Monorepos",{"path":2366,"title":2367},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fsharing-build-cache-across-ci-runners","Sharing Build Cache Across CI Runners",{"path":2369,"title":2370},"\u002Fproduction-ready-deployment-cicd-workflows","Production-Ready Deployment & CI\u002FCD for SSGs",{"path":2372,"title":2373},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Falerting-on-cache-hit-ratio-drops","Alerting on Cache Hit Ratio Drops",{"path":2375,"title":2376},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fbuilding-a-core-web-vitals-dashboard-from-rum-data","Building a Core Web Vitals Dashboard from RUM Data",{"path":2378,"title":2379},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fcrawling-for-broken-links-on-a-schedule","Crawling for Broken Links on a Schedule",{"path":2381,"title":2382},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Ffinding-the-cause-of-a-sudden-field-lcp-drop","Finding the Cause of a Sudden Field LCP Drop",{"path":2384,"title":1139},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production",{"path":2386,"title":2387},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Flogging-404s-at-the-edge","Logging 404s at the Edge",{"path":2389,"title":2390},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fmonitoring-tls-certificate-expiry","Monitoring TLS Certificate Expiry",{"path":2392,"title":2393},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Freal-user-error-tracking-on-static-sites","Real-User Error Tracking on Static Sites",{"path":2395,"title":2396},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fsynthetic-monitoring-with-scheduled-playwright-checks","Synthetic Monitoring With Scheduled Playwright Checks",{"path":2398,"title":2399},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Ftracking-deploy-markers-in-analytics","Tracking Deploy Markers in Analytics",{"path":2401,"title":2402},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fuptime-and-synthetic-checks-for-static-sites","Uptime and Synthetic Checks for Static Sites",{"path":2404,"title":2405},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fbandwidth-pricing-for-static-sites-across-netlify-vercel-and-cloudflare","Static Site Bandwidth Pricing: Netlify, Vercel, Cloudflare",{"path":2407,"title":2408},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fconfiguring-redirects-on-vercel-for-static-sites","Configuring Redirects on Vercel for Static Sites",{"path":2410,"title":2411},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fconfiguring-vercel-for-hugo-and-eleventy","Configuring Vercel for Hugo and Eleventy",{"path":2413,"title":2414},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fdeploying-astro-to-vercel-as-a-fully-static-site","Deploying Astro to Vercel as a Fully Static Site",{"path":2416,"title":2417},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Ffixing-netlify-builds-that-exceed-the-time-limit","Fixing Netlify Builds That Exceed the Time Limit",{"path":2419,"title":2420},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Ffixing-vercel-builds-that-run-out-of-memory","Fixing Vercel Builds That Run Out of Memory",{"path":2422,"title":29},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies",{"path":2424,"title":962},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-build-hooks-for-content-updates",{"path":2426,"title":2427},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-edge-functions-for-static-sites","Netlify Edge Functions for Static Sites",{"path":2429,"title":2430},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-redirects-and-rewrites-for-static-sites","Netlify Redirects and Rewrites for Static Sites",{"path":2432,"title":2433},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fsetting-up-deploy-previews-on-netlify-for-every-pull-request","Netlify Deploy Previews for Every Pull Request",{"path":2435,"title":2436},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fvercel-build-output-api-for-custom-ssgs","Vercel Build Output API for Custom SSGs",{"path":2438,"title":1415},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fvercel-isr-vs-static-generation-for-ssgs",{"path":2440,"title":2441},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fautomating-preview-deploy-pipelines-with-github-actions","Automating Preview Deploy Pipelines with GitHub Actions",{"path":2443,"title":2444},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fcleaning-up-stale-preview-deployments","Cleaning Up Stale Preview Deployments",{"path":2446,"title":2447},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fcommenting-on-preview-deploys","Commenting on Preview Deploys",{"path":2449,"title":2450},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Ffixing-preview-deploys-leaking-into-search-results","Fixing Preview Deploys Leaking Into Search Results",{"path":2452,"title":2453},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests","Preview Environments for Pull Requests",{"path":2455,"title":2456},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpassword-protecting-preview-deployments","Password-Protecting Preview Deployments",{"path":2458,"title":2459},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpreview-deploys-for-monorepos","Preview Deploys for Monorepos",{"path":2461,"title":2462},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpreviewing-headless-cms-drafts","Previewing Headless CMS Drafts",{"path":2464,"title":2465},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpull-request-previews-for-github-pages-sites","Pull Request Previews for GitHub Pages Sites",{"path":2467,"title":2468},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fvisual-regression-testing-on-preview-deploys","Visual Regression Testing on Preview Deploys",{"path":2470,"title":2471},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fatomic-deploys-vs-incremental-uploads","Atomic Deploys vs Incremental Uploads",{"path":2473,"title":2474},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fblue-green-deploys-for-static-sites","Blue-Green Deploys for Static Sites",{"path":2476,"title":2477},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fcanary-releases-for-static-sites","Canary Releases for Static Sites",{"path":2479,"title":2480},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Ffeature-flags-on-static-sites","Feature Flags on Static Sites",{"path":2482,"title":2483},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites","Rollbacks and Deploy Safety for Static Sites",{"path":2485,"title":2486},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fkeeping-old-assets-alive-after-deploy","Keeping Old Assets Alive After Deploy",{"path":2488,"title":2489},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fpost-deploy-verification-checklists","Post-Deploy Verification Checklists",{"path":2491,"title":2492},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Frecovering-from-a-deploy-that-deleted-live-assets","Recovering From a Deploy That Deleted Live Assets",{"path":2494,"title":2495},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Frolling-back-a-bad-static-deploy-in-under-a-minute","Rolling Back a Bad Static Deploy in Under a Minute",{"path":2497,"title":2498},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Frolling-back-netlify-deploys-from-the-cli-and-api","Rolling Back Netlify Deploys From the CLI and API",{"path":2500,"title":2501},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Frolling-back-s3-and-cloudfront-deploys-with-versioned-prefixes","Rolling Back S3 and CloudFront Deploys With Versioned Prefixes",{"path":2503,"title":2504},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Frunning-smoke-tests-against-a-preview-url","Running Smoke Tests Against a Preview URL",{"path":2506,"title":2507},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fauditing-npm-dependencies-in-ssg-pipelines","Auditing npm Dependencies in SSG Pipelines",{"path":2509,"title":2510},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fenabling-hsts-and-preload-safely","Enabling HSTS and Preload Safely",{"path":2512,"title":2513},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Ffixing-content-security-policy-violations-from-inline-scripts","Fixing Content Security Policy Violations From Inline Scripts",{"path":2515,"title":2516},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Ffixing-mixed-content-warnings-after-moving-to-https","Fixing Mixed Content Warnings After Moving to HTTPS",{"path":2518,"title":2519},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fhash-based-csp-for-inline-scripts-in-astro","Hash-Based CSP for Inline Scripts in Astro",{"path":2521,"title":2522},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites","Security Headers and Hardening for Static Sites",{"path":2524,"title":2525},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fpermissions-policy-and-cross-origin-headers","Permissions-Policy and Cross-Origin Headers",{"path":2527,"title":2528},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsecuring-deploy-credentials-with-github-oidc","Securing Deploy Credentials with GitHub OIDC",{"path":2530,"title":2531},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsecurity-headers-for-static-sites-served-by-caddy","Security Headers for Static Sites Served by Caddy",{"path":2533,"title":2534},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsecurity-headers-on-vercel-for-static-sites","Security Headers on Vercel for Static Sites",{"path":2536,"title":2537},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsecurity-txt-and-disclosure-for-static-sites","security.txt and Disclosure for Static Sites",{"path":2539,"title":2540},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsubresource-integrity-for-third-party-assets","Subresource Integrity for Third-Party Assets",{"path":2542,"title":2543},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fwriting-a-content-security-policy-for-a-static-site","Writing a Content Security Policy for a Static Site",{"path":2545,"title":2546},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fbrotli-and-gzip-precompression-served-by-nginx","Brotli and Gzip Precompression Served by Nginx",{"path":2548,"title":2549},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fclean-urls-and-trailing-slashes-on-s3","Clean URLs and Trailing Slashes on S3",{"path":2551,"title":2552},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fcloudfront-functions-for-redirects","CloudFront Functions for Redirects",{"path":2554,"title":2555},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fdeploying-a-static-site-to-s3-and-cloudfront","Deploying a Static Site to S3 and CloudFront",{"path":2557,"title":2558},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fhosting-on-azure-static-web-apps","Hosting on Azure Static Web Apps",{"path":2560,"title":2561},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites","Self-Hosting Static Sites on S3, Nginx and Caddy",{"path":2563,"title":2564},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fnginx-vs-caddy-for-serving-static-sites","Nginx vs Caddy for Serving Static Sites",{"path":2566,"title":2567},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-from-a-docker-container-with-nginx","Serving a Static Site From a Docker Container With Nginx",{"path":2569,"title":2570},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-caddy-and-automatic-https","Serving a Static Site With Caddy and Automatic HTTPS",{"path":2572,"title":2573},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-caddy","Serving a Static Site with Caddy",{"path":2575,"title":2576},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-nginx","Serving a Static Site with Nginx",{"path":2578,"title":2579},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fstatic-hosting-on-google-cloud-storage","Static Hosting on Google Cloud Storage",{"path":2581,"title":2582},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fzero-downtime-deploys-with-symlink-swaps","Zero-Downtime Deploys with Symlink Swaps",{"path":2584,"title":471},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fadding-a-contact-form-with-cloudflare-workers",{"path":2586,"title":1441},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Ffixing-cold-starts-in-netlify-functions-for-forms",{"path":2588,"title":466},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fhandling-form-submissions-on-a-static-site",{"path":1488,"title":5},{"path":2591,"title":332},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fnetlify-functions-vs-cloudflare-workers",{"path":2593,"title":1427},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fnewsletter-signup-with-an-edge-function",{"path":2595,"title":805},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fprotecting-a-static-site-behind-authentication",{"path":2597,"title":794},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fproxying-third-party-apis-from-an-edge-function",{"path":2599,"title":1434},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Frate-limiting-edge-functions",{"path":2601,"title":2602},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Faccessibility-testing-with-axe-and-pa11y-in-ci","Accessibility Testing with axe and pa11y in CI",{"path":2604,"title":2605},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Fend-to-end-tests-for-static-sites-with-playwright","End-to-End Tests for Static Sites with Playwright",{"path":2607,"title":2608},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Ffixing-flaky-playwright-tests-against-preview-deploys","Fixing Flaky Playwright Tests Against Preview Deploys",{"path":2610,"title":2611},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci","Testing Static Sites in CI",{"path":2613,"title":2614},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Fsnapshot-testing-build-output","Snapshot Testing Build Output",{"path":2616,"title":2617},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Ftesting-redirects-and-headers-before-deploy","Testing Redirects and Headers Before Deploy",{"path":2619,"title":2620},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Ftesting-search-and-navigation-flows-with-playwright","Testing Search and Navigation Flows With Playwright",{"path":2622,"title":2623},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Ftesting-structured-data-and-meta-tags","Testing Structured Data and Meta Tags",{"path":2625,"title":2626},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Fvalidating-html-output-in-ci","Validating HTML Output in CI",null,1790943190979]