[{"data":1,"prerenderedAt":2361},["ShallowReactive",2],{"page:\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Flogging-404s-at-the-edge":3,"all-docs-nav":1215,"filed:\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Flogging-404s-at-the-edge":2355},{"id":4,"title":5,"body":6,"breadcrumb":1191,"dateModified":1200,"datePublished":1200,"description":1201,"extension":1202,"faq":1203,"meta":1208,"navigation":1209,"path":1210,"seo":1211,"slug":12,"stem":1212,"type":1213,"__hash__":1214},"content\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Flogging-404s-at-the-edge\u002Findex.md","Logging 404s at the Edge",{"type":7,"value":8,"toc":1172},"minimark",[9,13,17,26,31,53,57,60,471,474,478,491,558,651,655,658,738,741,844,847,851,859,935,939,967,971,974,978,981,1051,1055,1087,1091,1094,1098,1103,1106,1110,1113,1117,1120,1124,1127,1131,1168],[10,11,5],"h1",{"id":12},"logging-404s-at-the-edge",[14,15,16],"p",{},"Every static site has a list of URLs that readers try and fail to reach: pages moved during a restructure without a redirect, links in old blog posts on other sites, bookmarks from a previous generator's URL scheme, typos in a popular forum answer. Those 404s are invisible to the build, rarely reported by readers, and — because they come from outside — impossible to find by crawling your own site. The one place they are all recorded is the CDN's request log.",[14,18,19,20,25],{},"This guide collects 404s from the edge on Cloudflare and CloudFront, filters out bot noise, ranks paths by reader impact and turns the top of the list into redirects on a weekly cadence. It is part of ",[21,22,24],"a",{"href":23},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002F","Monitoring Static Sites in Production",".",[27,28,30],"h2",{"id":29},"prerequisites","Prerequisites",[32,33,34,38,50],"ul",{},[35,36,37],"li",{},"Access to the CDN's request logs or analytics: Cloudflare Logpush or Workers Analytics Engine, CloudFront standard logs to S3, or an equivalent.",[35,39,40,41,45,46,25],{},"A redirect mechanism for the host — see ",[21,42,44],{"href":43},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fconfiguring-redirects-on-cloudflare-pages\u002F","Configuring Redirects on Cloudflare Pages"," or ",[21,47,49],{"href":48},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fcloudfront-functions-for-redirects\u002F","CloudFront Functions for Redirects",[35,51,52],{},"A place to run a weekly query: Athena, BigQuery, ClickHouse, or the CDN's own GraphQL API.",[27,54,56],{"id":55},"step-1-capture-404s-with-their-context","Step 1: Capture 404s With Their Context",[14,58,59],{},"A 404 count per path is not enough to act on; you need to know where readers came from. Record path, referrer, user agent class and country for every 404. On Cloudflare, a small Worker in front of static assets can write that to Workers Analytics Engine without any log pipeline:",[61,62,67],"pre",{"className":63,"code":64,"language":65,"meta":66,"style":66},"language-js shiki shiki-themes github-light github-dark","\u002F\u002F worker.js — wraps static assets, records 404s\nexport default {\n  async fetch(request, env, ctx) {\n    const res = await env.ASSETS.fetch(request);\n    if (res.status === 404) {\n      const url = new URL(request.url);\n      const ua = request.headers.get('user-agent') ?? '';\n      ctx.waitUntil(Promise.resolve(env.NOTFOUND.writeDataPoint({\n        blobs: [url.pathname, request.headers.get('referer') ?? '', uaClass(ua), request.cf?.country ?? ''],\n        indexes: [url.pathname.slice(0, 96)],\n      })));\n    }\n    return res;\n  },\n};\nconst uaClass = (ua) => \u002Fbot|crawl|spider|scan|curl|python|go-http\u002Fi.test(ua) ? 'bot'\n  : \u002FMozilla\\\u002F5\\.0\u002F.test(ua) ? 'browser' : 'other';\n","js","",[68,69,70,79,93,124,154,171,191,225,258,292,314,320,326,335,341,347,427],"code",{"__ignoreMap":66},[71,72,75],"span",{"class":73,"line":74},"line",1,[71,76,78],{"class":77},"sJ8bj","\u002F\u002F worker.js — wraps static assets, records 404s\n",[71,80,82,86,89],{"class":73,"line":81},2,[71,83,85],{"class":84},"szBVR","export",[71,87,88],{"class":84}," default",[71,90,92],{"class":91},"sVt8B"," {\n",[71,94,96,99,103,106,110,113,116,118,121],{"class":73,"line":95},3,[71,97,98],{"class":84},"  async",[71,100,102],{"class":101},"sScJk"," fetch",[71,104,105],{"class":91},"(",[71,107,109],{"class":108},"s4XuR","request",[71,111,112],{"class":91},", ",[71,114,115],{"class":108},"env",[71,117,112],{"class":91},[71,119,120],{"class":108},"ctx",[71,122,123],{"class":91},") {\n",[71,125,127,130,134,137,140,143,146,148,151],{"class":73,"line":126},4,[71,128,129],{"class":84},"    const",[71,131,133],{"class":132},"sj4cs"," res",[71,135,136],{"class":84}," =",[71,138,139],{"class":84}," await",[71,141,142],{"class":91}," env.",[71,144,145],{"class":132},"ASSETS",[71,147,25],{"class":91},[71,149,150],{"class":101},"fetch",[71,152,153],{"class":91},"(request);\n",[71,155,157,160,163,166,169],{"class":73,"line":156},5,[71,158,159],{"class":84},"    if",[71,161,162],{"class":91}," (res.status ",[71,164,165],{"class":84},"===",[71,167,168],{"class":132}," 404",[71,170,123],{"class":91},[71,172,174,177,180,182,185,188],{"class":73,"line":173},6,[71,175,176],{"class":84},"      const",[71,178,179],{"class":132}," url",[71,181,136],{"class":84},[71,183,184],{"class":84}," new",[71,186,187],{"class":101}," URL",[71,189,190],{"class":91},"(request.url);\n",[71,192,194,196,199,201,204,207,209,213,216,219,222],{"class":73,"line":193},7,[71,195,176],{"class":84},[71,197,198],{"class":132}," ua",[71,200,136],{"class":84},[71,202,203],{"class":91}," request.headers.",[71,205,206],{"class":101},"get",[71,208,105],{"class":91},[71,210,212],{"class":211},"sZZnC","'user-agent'",[71,214,215],{"class":91},") ",[71,217,218],{"class":84},"??",[71,220,221],{"class":211}," ''",[71,223,224],{"class":91},";\n",[71,226,228,231,234,236,239,241,244,247,250,252,255],{"class":73,"line":227},8,[71,229,230],{"class":91},"      ctx.",[71,232,233],{"class":101},"waitUntil",[71,235,105],{"class":91},[71,237,238],{"class":132},"Promise",[71,240,25],{"class":91},[71,242,243],{"class":101},"resolve",[71,245,246],{"class":91},"(env.",[71,248,249],{"class":132},"NOTFOUND",[71,251,25],{"class":91},[71,253,254],{"class":101},"writeDataPoint",[71,256,257],{"class":91},"({\n",[71,259,261,264,266,268,271,273,275,277,279,282,285,287,289],{"class":73,"line":260},9,[71,262,263],{"class":91},"        blobs: [url.pathname, request.headers.",[71,265,206],{"class":101},[71,267,105],{"class":91},[71,269,270],{"class":211},"'referer'",[71,272,215],{"class":91},[71,274,218],{"class":84},[71,276,221],{"class":211},[71,278,112],{"class":91},[71,280,281],{"class":101},"uaClass",[71,283,284],{"class":91},"(ua), request.cf?.country ",[71,286,218],{"class":84},[71,288,221],{"class":211},[71,290,291],{"class":91},"],\n",[71,293,295,298,301,303,306,308,311],{"class":73,"line":294},10,[71,296,297],{"class":91},"        indexes: [url.pathname.",[71,299,300],{"class":101},"slice",[71,302,105],{"class":91},[71,304,305],{"class":132},"0",[71,307,112],{"class":91},[71,309,310],{"class":132},"96",[71,312,313],{"class":91},")],\n",[71,315,317],{"class":73,"line":316},11,[71,318,319],{"class":91},"      })));\n",[71,321,323],{"class":73,"line":322},12,[71,324,325],{"class":91},"    }\n",[71,327,329,332],{"class":73,"line":328},13,[71,330,331],{"class":84},"    return",[71,333,334],{"class":91}," res;\n",[71,336,338],{"class":73,"line":337},14,[71,339,340],{"class":91},"  },\n",[71,342,344],{"class":73,"line":343},15,[71,345,346],{"class":91},"};\n",[71,348,350,353,356,358,361,364,366,369,372,376,379,382,384,387,389,392,394,397,399,402,404,407,410,413,415,418,421,424],{"class":73,"line":349},16,[71,351,352],{"class":84},"const",[71,354,355],{"class":101}," uaClass",[71,357,136],{"class":84},[71,359,360],{"class":91}," (",[71,362,363],{"class":108},"ua",[71,365,215],{"class":91},[71,367,368],{"class":84},"=>",[71,370,371],{"class":211}," \u002F",[71,373,375],{"class":374},"sA_wV","bot",[71,377,378],{"class":84},"|",[71,380,381],{"class":374},"crawl",[71,383,378],{"class":84},[71,385,386],{"class":374},"spider",[71,388,378],{"class":84},[71,390,391],{"class":374},"scan",[71,393,378],{"class":84},[71,395,396],{"class":374},"curl",[71,398,378],{"class":84},[71,400,401],{"class":374},"python",[71,403,378],{"class":84},[71,405,406],{"class":374},"go-http",[71,408,409],{"class":211},"\u002F",[71,411,412],{"class":84},"i",[71,414,25],{"class":91},[71,416,417],{"class":101},"test",[71,419,420],{"class":91},"(ua) ",[71,422,423],{"class":84},"?",[71,425,426],{"class":211}," 'bot'\n",[71,428,430,433,435,438,442,445,448,450,452,454,456,458,460,463,466,469],{"class":73,"line":429},17,[71,431,432],{"class":84},"  :",[71,434,371],{"class":211},[71,436,437],{"class":374},"Mozilla",[71,439,441],{"class":440},"snhLl","\\\u002F",[71,443,444],{"class":374},"5",[71,446,447],{"class":440},"\\.",[71,449,305],{"class":374},[71,451,409],{"class":211},[71,453,25],{"class":91},[71,455,417],{"class":101},[71,457,420],{"class":91},[71,459,423],{"class":84},[71,461,462],{"class":211}," 'browser'",[71,464,465],{"class":84}," :",[71,467,468],{"class":211}," 'other'",[71,470,224],{"class":91},[14,472,473],{},"On CloudFront, standard logs already contain status, URI, referrer and user agent; point an Athena table at the log bucket and query it directly.",[27,475,477],{"id":476},"step-2-filter-out-the-noise","Step 2: Filter Out the Noise",[14,479,480,481,112,484,112,487,490],{},"Most raw 404s on the public internet are not readers. Vulnerability scanners probe ",[68,482,483],{},"\u002Fwp-login.php",[68,485,486],{},"\u002F.env",[68,488,489],{},"\u002F.git\u002Fconfig"," and thousands of similar paths on every site. On the documentation site measured here, 91% of raw 404 requests were bots. Filter before ranking:",[61,492,496],{"className":493,"code":494,"language":495,"meta":66,"style":66},"language-sql shiki shiki-themes github-light github-dark","-- Athena over CloudFront logs: last 7 days of reader-facing 404s\nSELECT uri, count(*) AS hits,\n       count(DISTINCT referrer) AS referrers,\n       approx_percentile(length(referrer), 0.5) > 1 AS usually_referred\nFROM cloudfront_logs\nWHERE status = 404 AND date >= current_date - interval '7' day\n  AND user_agent LIKE 'Mozilla\u002F5.0%'\n  AND NOT regexp_like(user_agent, '(?i)bot|crawl|spider|scan')\n  AND NOT regexp_like(uri, '(?i)\\.(php|asp|aspx|env|git|bak|sql|zip)$|wp-|\u002Fcgi-bin\u002F|\u002F\\.')\nGROUP BY uri\nORDER BY hits DESC\nLIMIT 50;\n","sql",[68,497,498,503,508,513,518,523,528,533,538,543,548,553],{"__ignoreMap":66},[71,499,500],{"class":73,"line":74},[71,501,502],{},"-- Athena over CloudFront logs: last 7 days of reader-facing 404s\n",[71,504,505],{"class":73,"line":81},[71,506,507],{},"SELECT uri, count(*) AS hits,\n",[71,509,510],{"class":73,"line":95},[71,511,512],{},"       count(DISTINCT referrer) AS referrers,\n",[71,514,515],{"class":73,"line":126},[71,516,517],{},"       approx_percentile(length(referrer), 0.5) > 1 AS usually_referred\n",[71,519,520],{"class":73,"line":156},[71,521,522],{},"FROM cloudfront_logs\n",[71,524,525],{"class":73,"line":173},[71,526,527],{},"WHERE status = 404 AND date >= current_date - interval '7' day\n",[71,529,530],{"class":73,"line":193},[71,531,532],{},"  AND user_agent LIKE 'Mozilla\u002F5.0%'\n",[71,534,535],{"class":73,"line":227},[71,536,537],{},"  AND NOT regexp_like(user_agent, '(?i)bot|crawl|spider|scan')\n",[71,539,540],{"class":73,"line":260},[71,541,542],{},"  AND NOT regexp_like(uri, '(?i)\\.(php|asp|aspx|env|git|bak|sql|zip)$|wp-|\u002Fcgi-bin\u002F|\u002F\\.')\n",[71,544,545],{"class":73,"line":294},[71,546,547],{},"GROUP BY uri\n",[71,549,550],{"class":73,"line":316},[71,551,552],{},"ORDER BY hits DESC\n",[71,554,555],{"class":73,"line":322},[71,556,557],{},"LIMIT 50;\n",[559,560,561,647],"figure",{},[562,563,570,571,570,575,570,579,570,585],"svg",{"viewBox":564,"role":565,"ariaLabelledBy":566,"xmlns":569},"0 0 760 270","img",[567,568],"e404-noise-title","e404-noise-desc","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","\n  ",[572,573,574],"title",{"id":567},"Raw 404s versus reader 404s",[576,577,578],"desc",{"id":568},"A stacked bar of 404 requests in one week. Of 184,000 raw 404s, 167,000 were bots and scanners, 4,500 were browsers requesting probe-like paths, and 12,500 were readers following real links, which is the part worth acting on.",[580,581],"rect",{"x":305,"y":305,"width":582,"height":583,"fill":584},"760","270","#ffffff",[586,587,589,590,589,598,589,607,589,613,589,620,589,626,589,633,589,637,589,643,570],"g",{"style":588},"font-family:system-ui, sans-serif;font-size:12px","\n    ",[591,592,597],"text",{"x":593,"y":594,"fill":595,"style":596},"380","28","#1f2937","font-size:16px;font-weight:700;text-anchor:middle","One week of 404s, before and after filtering",[580,599],{"x":600,"y":601,"width":602,"height":603,"fill":604,"stroke":605,"style":606},"40","70","620","44","#f8fafc","#556071","stroke-width:1px",[591,608,612],{"x":609,"y":610,"fill":595,"style":611},"350","97","text-anchor:middle","bots and scanners · 167,000 (91%)",[580,614],{"x":615,"y":601,"width":616,"height":603,"fill":617,"opacity":618,"stroke":619,"style":606},"660","17","#ffca3a","0.4","#a97b00",[580,621],{"x":622,"y":601,"width":623,"height":603,"fill":624,"opacity":618,"stroke":625,"style":606},"677","46","#8ac926","#5a8a16",[591,627,632],{"x":628,"y":629,"fill":630,"style":631},"700","138","#3f6410","font-size:11px;font-weight:700;text-anchor:middle","readers",[591,634,636],{"x":628,"y":635,"fill":630,"style":631},"154","12,500",[591,638,642],{"x":602,"y":639,"fill":640,"style":641},"176","#8a6d0f","font-size:11px;text-anchor:middle","probe-like paths from browsers · 4,500",[591,644,646],{"x":593,"y":645,"fill":605,"style":641},"230","Ranking unfiltered 404s puts \u002Fwp-login.php at the top of a site that has never run WordPress",[648,649,650],"figcaption",{},"The actionable part of the 404 log is under a tenth of it; filtering is what makes the report readable.",[27,652,654],{"id":653},"step-3-rank-by-reader-impact-and-decide","Step 3: Rank by Reader Impact and Decide",[14,656,657],{},"For each path in the top fifty, decide one of four outcomes:",[659,660,661,677],"table",{},[662,663,664],"thead",{},[665,666,667,671,674],"tr",{},[668,669,670],"th",{},"Situation",[668,672,673],{},"Action",[668,675,676],{},"Example",[678,679,680,698,714,725],"tbody",{},[665,681,682,686,689],{},[683,684,685],"td",{},"Content moved; clear equivalent exists",[683,687,688],{},"301 redirect",[683,690,691,694,695],{},[68,692,693],{},"\u002Fdocs\u002Finstall"," → ",[68,696,697],{},"\u002Fguides\u002Finstall\u002F",[665,699,700,703,706],{},[683,701,702],{},"Old URL pattern from a previous generator",[683,704,705],{},"pattern redirect",[683,707,708,694,711],{},[68,709,710],{},"\u002Fblog\u002F2021\u002F03\u002Fslug.html",[68,712,713],{},"\u002Fblog\u002Fslug\u002F",[665,715,716,719,722],{},[683,717,718],{},"Content deliberately removed",[683,720,721],{},"410 Gone, or 404 with a helpful page",[683,723,724],{},"retired product docs",[665,726,727,730,733],{},[683,728,729],{},"Typo in an external link, heavy traffic",[683,731,732],{},"redirect, and ask the linking site to fix it",[683,734,735],{},[68,736,737],{},"\u002Fguides\u002Fintsall\u002F",[14,739,740],{},"Referrers tell you which: a 404 whose referrer is your own site is an internal broken link to fix at the source; one whose referrer is a search engine means an indexed URL that needs a redirect; one whose referrer is a single external page means one link somewhere is wrong.",[559,742,743,841],{},[562,744,570,749,570,752,570,755,570,758,570,828],{"viewBox":745,"role":565,"ariaLabelledBy":746,"xmlns":569},"0 0 760 260",[747,748],"e404-ref-title","e404-ref-desc",[572,750,751],{"id":747},"The referrer decides the fix",[576,753,754],{"id":748},"Three referrer types lead to three fixes. A referrer on your own site means an internal broken link: fix the link in the source. A search engine referrer means an indexed old URL: add a redirect. A single external page as referrer means one wrong link elsewhere: add a redirect if traffic is significant and contact the linking site.",[580,756],{"x":305,"y":305,"width":582,"height":757,"fill":584},"260",[586,759,589,760,589,763,589,772,589,778,589,780,589,784,589,786,589,789,589,796,589,800,589,803,589,806,589,809,589,812,570],{"style":588},[591,761,762],{"x":593,"y":594,"fill":595,"style":596},"Where the reader came from tells you what to fix",[580,764],{"x":765,"y":766,"width":767,"height":768,"rx":769,"fill":604,"stroke":770,"style":771},"30","60","200","50","8","#d9e2ef","stroke-width:1.5px",[591,773,777],{"x":774,"y":775,"fill":595,"style":776},"130","90","font-weight:700;text-anchor:middle","your own site",[580,779],{"x":765,"y":774,"width":767,"height":768,"rx":769,"fill":604,"stroke":770,"style":771},[591,781,783],{"x":774,"y":782,"fill":595,"style":776},"160","search engine",[580,785],{"x":765,"y":767,"width":767,"height":768,"rx":769,"fill":604,"stroke":770,"style":771},[591,787,788],{"x":774,"y":645,"fill":595,"style":776},"one external page",[580,790],{"x":791,"y":766,"width":792,"height":768,"rx":769,"fill":793,"opacity":794,"stroke":795,"style":771},"330","400","#ff595e","0.14","#d83b41",[591,797,799],{"x":798,"y":775,"fill":595,"style":611},"530","fix the link in your source; no redirect needed",[580,801],{"x":791,"y":774,"width":792,"height":768,"rx":769,"fill":624,"opacity":802,"stroke":625,"style":771},"0.18",[591,804,805],{"x":798,"y":782,"fill":595,"style":611},"add a 301 to the equivalent page",[580,807],{"x":791,"y":767,"width":792,"height":768,"rx":769,"fill":617,"opacity":808,"stroke":619,"style":771},"0.24",[591,810,811],{"x":798,"y":645,"fill":595,"style":611},"redirect if busy; ask the linking site to update",[586,813,816,817,816,822,816,825,589],{"stroke":605,"fill":814,"style":815},"none","stroke-width:2px","\n      ",[818,819],"path",{"d":820,"style":821},"M232 85 L326 85","marker-end:url(#e404-arrow)",[818,823],{"d":824,"style":821},"M232 155 L326 155",[818,826],{"d":827,"style":821},"M232 225 L326 225",[829,830,589,831,570],"defs",{},[832,833,816,838,589],"marker",{"id":834,"viewBox":835,"refX":769,"refY":444,"markerWidth":836,"markerHeight":836,"orient":837},"e404-arrow","0 0 10 10","7","auto-start-reverse",[818,839],{"d":840,"fill":605},"M0 0 L10 5 L0 10 z",[648,842,843],{},"Same-site referrers are the most valuable find: they are bugs in your own content that every reader of that page can hit.",[14,845,846],{},"On the restructured docs site, 23 of the top fifty 404 paths had same-site referrers — links inside the docs that the restructure had not updated, mostly in pages written in raw HTML where the link checker's Markdown parser had not looked. Fixing those at the source removed the 404 and the need for a redirect at the same time. Another 19 came from search engines and got redirects. The remaining eight each came from one external page, usually a forum answer or a partner's documentation; for the five with meaningful traffic, a redirect plus a short note to the linking site's maintainer fixed it permanently.",[27,848,850],{"id":849},"step-4-make-it-a-weekly-loop","Step 4: Make It a Weekly Loop",[14,852,853,854,858],{},"Run the query weekly, post the top twenty to the team channel with a suggested action for each, and add redirects in a pull request the same week. Redirect targets are verified by the build, as described in ",[21,855,857],{"href":856},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fkeeping-redirects-working-after-an-ssg-migration\u002F","Keeping Redirects Working After an SSG Migration",". Add an alert for spikes: a path that goes from zero to more than 100 reader 404s in an hour almost always means a deploy removed or renamed something popular.",[559,860,861,932],{},[562,862,570,866,570,869,570,872,570,874],{"viewBox":564,"role":565,"ariaLabelledBy":863,"xmlns":569},[864,865],"e404-trend-title","e404-trend-desc",[572,867,868],{"id":864},"Reader 404s per day over eight weeks of weekly fixes",[576,870,871],{"id":865},"A falling line of reader 404s per day. It starts at about 1,800 per day in week one after a site restructure, drops to about 700 after the first batch of 15 redirects, to about 300 after week three, and levels off around 180 per day from week five onward.",[580,873],{"x":305,"y":305,"width":582,"height":583,"fill":584},[586,875,589,876,589,879,589,883,589,885,589,890,589,894,589,898,589,904,589,909,589,915,589,920,589,924,589,928,570],{"style":588},[591,877,878],{"x":593,"y":594,"fill":595,"style":596},"Reader 404s per day, weekly redirect batches",[73,880],{"x1":601,"y1":881,"x2":882,"y2":881,"stroke":605,"style":771},"220","720",[73,884],{"x1":601,"y1":768,"x2":601,"y2":881,"stroke":605,"style":771},[591,886,305],{"x":887,"y":888,"fill":605,"style":889},"62","224","font-size:11px;text-anchor:end",[591,891,893],{"x":887,"y":892,"fill":605,"style":889},"136","1,000",[591,895,897],{"x":887,"y":896,"fill":605,"style":889},"54","2,000",[899,900],"polyline",{"points":901,"fill":814,"stroke":902,"style":903},"90,62 170,64 250,158 330,194 410,200 490,204 570,205 650,204 710,205","#6a4c93","stroke-width:2.5px",[591,905,908],{"x":310,"y":906,"fill":902,"style":907},"56","font-size:11px;font-weight:700","~1,800 \u002F day",[591,910,914],{"x":911,"y":912,"fill":595,"style":913},"256","150","font-size:11px","15 redirects",[591,916,919],{"x":917,"y":918,"fill":595,"style":913},"336","186","+22",[591,921,923],{"x":602,"y":922,"fill":630,"style":907},"196","~180 \u002F day",[591,925,927],{"x":775,"y":926,"fill":605,"style":641},"240","wk 1",[591,929,931],{"x":930,"y":926,"fill":605,"style":641},"710","wk 8",[648,933,934],{},"Two weekly batches of redirects removed most of the reader-facing 404s; the remainder is a scattering of one-off typos.",[27,936,938],{"id":937},"other-status-codes-worth-watching","Other Status Codes Worth Watching",[14,940,941,942,946,947,45,950,953,954,958,959,962,963,966],{},"The same log pipeline answers adjacent questions cheaply. Count ",[943,944,945],"strong",{},"410 and 404 responses on asset paths"," separately from pages: a spike in missing ",[68,948,949],{},".js",[68,951,952],{},".css"," files usually follows a deploy that removed old hashed assets while cached HTML still referenced them, which is covered in ",[21,955,957],{"href":956},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fatomic-deploys-vs-incremental-uploads\u002F","Atomic Deploys vs Incremental Uploads",". Count ",[943,960,961],{},"301 responses by path",": a redirect that serves thousands of hits a week points at an internal link or sitemap entry that should be updated to the final URL, saving every reader a round trip. And watch ",[943,964,965],{},"5xx responses",", which on a static host should be essentially zero; any at all usually mean an edge function throwing or an origin misconfiguration on self-hosted setups.",[27,968,970],{"id":969},"make-the-404-page-useful","Make the 404 Page Useful",[14,972,973],{},"Some 404s will always remain, so the page readers land on matters. A static 404 page can still help: include a search box, links to the main sections, and — because it is generated at build time — a short list of pages whose paths share words with common mistyped URLs. A few lines of client-side script can suggest the closest existing path by comparing the requested URL with the sitemap. On this site, adding a search box and \"did you mean\" suggestion to the 404 page meant 41% of readers who hit a 404 clicked through to a real page, against 12% before. Make sure the page returns a real 404 status — hosts serve custom 404 pages correctly by default, but single-page-app fallback settings can turn them into soft 200s that search engines index.",[27,975,977],{"id":976},"measured-impact","Measured Impact",[14,979,980],{},"Eight weeks after a documentation restructure moved 340 pages:",[659,982,983,996],{},[662,984,985],{},[665,986,987,990,993],{},[668,988,989],{},"Measure",[668,991,992],{},"Week 1",[668,994,995],{},"Week 8",[678,997,998,1009,1019,1029,1040],{},[665,999,1000,1003,1006],{},[683,1001,1002],{},"Reader 404s per day",[683,1004,1005],{},"~1,800",[683,1007,1008],{},"~180",[665,1010,1011,1014,1016],{},[683,1012,1013],{},"Redirects added from the log",[683,1015,305],{},[683,1017,1018],{},"61",[665,1020,1021,1024,1027],{},[683,1022,1023],{},"Internal broken links found via same-site referrers",[683,1025,1026],{},"23",[683,1028,305],{},[665,1030,1031,1034,1037],{},[683,1032,1033],{},"Search Console \"Not found (404)\" URLs",[683,1035,1036],{},"290",[683,1038,1039],{},"34",[665,1041,1042,1045,1048],{},[683,1043,1044],{},"404-page click-through to a real page",[683,1046,1047],{},"12%",[683,1049,1050],{},"41%",[27,1052,1054],{"id":1053},"pitfalls-rollback","Pitfalls & Rollback",[32,1056,1057,1063,1069,1075,1081],{},[35,1058,1059,1062],{},[943,1060,1061],{},"Ranking unfiltered logs."," Bot probes dominate raw 404s. Filter by user agent and path pattern before looking.",[35,1064,1065,1068],{},[943,1066,1067],{},"Redirecting everything to the homepage."," Search engines treat that as a soft 404, and readers lose context. Redirect to an equivalent page or return 404.",[35,1070,1071,1074],{},[943,1072,1073],{},"Keeping raw IPs indefinitely."," They are personal data in many jurisdictions; truncate or drop them.",[35,1076,1077,1080],{},[943,1078,1079],{},"A 404 page that returns 200."," Check the status explicitly; SPA fallbacks often break it.",[35,1082,1083,1086],{},[943,1084,1085],{},"Rollback:"," the logging Worker or Athena table is independent of the site. Removing it stops collection without affecting pages.",[27,1088,1090],{"id":1089},"conclusion","Conclusion",[14,1092,1093],{},"Edge logs are the only complete record of the URLs readers fail to reach. Capturing each 404 with its referrer and user agent, filtering the 91% that are bots, and acting weekly on the top of the ranked list cut reader-facing 404s on a restructured docs site by 90% in eight weeks, with 61 redirects. A 404 page with search and suggestions turned many of the rest into successful visits.",[27,1095,1097],{"id":1096},"faq","FAQ",[1099,1100,1102],"h3",{"id":1101},"why-log-404s-at-the-edge-instead-of-in-analytics","Why log 404s at the edge instead of in analytics?",[14,1104,1105],{},"Analytics scripts run in the browser and often do not load on error pages, and many readers block them. The CDN sees every request, including those from links in other sites, feed readers and bots, so its logs are the complete record.",[1099,1107,1109],{"id":1108},"how-do-i-tell-bot-404s-from-reader-404s","How do I tell bot 404s from reader 404s?",[14,1111,1112],{},"Look at the referrer and user agent. Reader 404s usually have a referrer from a search engine, another site or your own pages, and a browser user agent. Bot probes for paths like \u002Fwp-admin or \u002F.env have no referrer and scanner user agents. Filter them out before ranking.",[1099,1114,1116],{"id":1115},"should-every-404-get-a-redirect","Should every 404 get a redirect?",[14,1118,1119],{},"No. Redirect paths that readers actually reach and that have a clear equivalent page. Leave probes, typos with no pattern and paths for content that was deliberately removed as 404 or 410.",[1099,1121,1123],{"id":1122},"how-long-should-404-logs-be-kept","How long should 404 logs be kept?",[14,1125,1126],{},"Thirty to ninety days is enough to see patterns and seasonal traffic. Aggregate counts per path can be kept longer; drop raw IP addresses or truncate them to respect privacy.",[27,1128,1130],{"id":1129},"related","Related",[32,1132,1133,1142,1149,1154,1161],{},[35,1134,1135,1138,1139,1141],{},[943,1136,1137],{},"Parent:"," ",[21,1140,24],{"href":23}," — the full monitoring set.",[35,1143,1144,1148],{},[21,1145,1147],{"href":1146},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fcrawling-for-broken-links-on-a-schedule\u002F","Crawling for Broken Links on a Schedule"," — broken links going out; this page covers links coming in.",[35,1150,1151,1153],{},[21,1152,857],{"href":856}," — preventing the restructure spike.",[35,1155,1156,1160],{},[21,1157,1159],{"href":1158},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-redirects-and-rewrites-for-static-sites\u002F","Netlify Redirects and Rewrites for Static Sites"," — applying the fixes on Netlify.",[35,1162,1163,1167],{},[21,1164,1166],{"href":1165},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Falerting-on-cache-hit-ratio-drops\u002F","Alerting on Cache Hit Ratio Drops"," — another signal from the same logs.",[1169,1170,1171],"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 .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}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 pre.shiki code .sA_wV, html code.shiki .sA_wV{--shiki-default:#032F62;--shiki-dark:#DBEDFF}html pre.shiki code .snhLl, html code.shiki .snhLl{--shiki-default:#22863A;--shiki-default-font-weight:bold;--shiki-dark:#85E89D;--shiki-dark-font-weight:bold}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":66,"searchDepth":81,"depth":81,"links":1173},[1174,1175,1176,1177,1178,1179,1180,1181,1182,1183,1184,1190],{"id":29,"depth":81,"text":30},{"id":55,"depth":81,"text":56},{"id":476,"depth":81,"text":477},{"id":653,"depth":81,"text":654},{"id":849,"depth":81,"text":850},{"id":937,"depth":81,"text":938},{"id":969,"depth":81,"text":970},{"id":976,"depth":81,"text":977},{"id":1053,"depth":81,"text":1054},{"id":1089,"depth":81,"text":1090},{"id":1096,"depth":81,"text":1097,"children":1185},[1186,1187,1188,1189],{"id":1101,"depth":95,"text":1102},{"id":1108,"depth":95,"text":1109},{"id":1115,"depth":95,"text":1116},{"id":1122,"depth":95,"text":1123},{"id":1129,"depth":81,"text":1130},[1192,1194,1197,1198],{"name":1193,"item":409},"Home",{"name":1195,"item":1196},"Production-Ready Deployment & CI\u002FCD Workflows","\u002Fproduction-ready-deployment-cicd-workflows\u002F",{"name":24,"item":23},{"name":5,"item":1199},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Flogging-404s-at-the-edge\u002F","2026-09-18","Collect every 404 a static site serves at the CDN edge, rank paths by reader impact, separate bots from people, and turn the top of the list into redirects.","md",[1204,1205,1206,1207],{"q":1102,"a":1105},{"q":1109,"a":1112},{"q":1116,"a":1119},{"q":1123,"a":1126},{},true,"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Flogging-404s-at-the-edge",{"title":5,"description":1201},"production-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Flogging-404s-at-the-edge\u002Findex","article","NKiawgbCTghpNyyxoMJlict7wk1DbU2UzwwSitNZpX4",[1216,1219,1222,1225,1228,1231,1234,1237,1240,1243,1246,1249,1252,1255,1258,1261,1264,1267,1270,1273,1276,1279,1282,1285,1288,1291,1294,1297,1300,1303,1306,1309,1312,1315,1318,1321,1324,1327,1330,1333,1336,1339,1342,1345,1348,1351,1354,1357,1360,1363,1366,1369,1372,1375,1378,1381,1384,1387,1390,1393,1396,1399,1402,1405,1408,1411,1414,1417,1420,1423,1426,1429,1432,1435,1438,1441,1444,1447,1449,1452,1455,1458,1461,1464,1467,1470,1473,1476,1479,1482,1485,1488,1491,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,1967,1970,1973,1976,1979,1982,1985,1988,1991,1994,1997,2000,2003,2006,2009,2012,2015,2018,2021,2024,2027,2030,2033,2036,2039,2042,2045,2048,2051,2054,2057,2060,2063,2066,2069,2072,2075,2078,2081,2084,2087,2090,2093,2095,2098,2100,2103,2105,2106,2109,2112,2115,2118,2121,2124,2127,2130,2133,2136,2139,2142,2145,2148,2150,2153,2156,2159,2162,2165,2168,2171,2174,2177,2180,2183,2186,2189,2191,2194,2197,2200,2203,2206,2209,2212,2215,2218,2221,2224,2227,2230,2233,2236,2239,2242,2245,2248,2251,2254,2257,2260,2263,2266,2269,2271,2274,2277,2280,2283,2286,2289,2292,2295,2298,2301,2304,2307,2310,2313,2316,2319,2322,2325,2328,2331,2334,2337,2340,2343,2346,2349,2352],{"path":1217,"title":1218},"\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":1220,"title":1221},"\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":1223,"title":1224},"\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":1226,"title":1227},"\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":1229,"title":1230},"\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":1232,"title":1233},"\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":1235,"title":1236},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Faccessibility-for-static-sites","Accessibility for Static Sites",{"path":1238,"title":1239},"\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":1241,"title":1242},"\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":1244,"title":1245},"\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":1247,"title":1248},"\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":1250,"title":1251},"\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":1253,"title":1254},"\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":1256,"title":1257},"\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":1259,"title":1260},"\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":1262,"title":1263},"\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":1265,"title":1266},"\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":1268,"title":1269},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites","Astro vs Eleventy for Documentation Sites",{"path":1271,"title":1272},"\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":1274,"title":1275},"\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":1277,"title":1278},"\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":1280,"title":1281},"\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":1283,"title":1284},"\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":1286,"title":1287},"\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":1289,"title":1290},"\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":1292,"title":1293},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fcomparing-docs-framework-build-times","Comparing Docs Framework Build Times",{"path":1295,"title":1296},"\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":1298,"title":1299},"\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":1301,"title":1302},"\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":1304,"title":1305},"\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":1307,"title":1308},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress","Docs Frameworks: Docusaurus, Starlight and VitePress",{"path":1310,"title":1311},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Finternationalizing-starlight-docs","Internationalizing Starlight Docs",{"path":1313,"title":1314},"\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":1316,"title":1317},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fmigrating-from-mkdocs-to-starlight","Migrating from MkDocs to Starlight",{"path":1319,"title":1320},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fmigrating-mkdocs-documentation-to-vitepress","Migrating MkDocs Documentation to VitePress",{"path":1322,"title":1323},"\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":1325,"title":1326},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fversioned-documentation-with-docusaurus","Versioned Documentation with Docusaurus",{"path":1328,"title":1329},"\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":1331,"title":1332},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fvitepress-for-library-documentation","VitePress for Library Documentation",{"path":1334,"title":1335},"\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":1337,"title":1338},"\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":1340,"title":1341},"\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":1343,"title":1344},"\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":1346,"title":1347},"\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":1349,"title":1350},"\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":1352,"title":1353},"\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":1355,"title":1356},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories","Hugo Build Times for Large Repositories",{"path":1358,"title":1359},"\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":1361,"title":1362},"\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":1364,"title":1365},"\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":1367,"title":1368},"\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":1370,"title":1371},"\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":1373,"title":1374},"\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":1376,"title":1377},"\u002Fchoosing-the-right-static-site-generator-for-production","Choosing the Right Static Site Generator for Production",{"path":1379,"title":1380},"\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":1382,"title":1383},"\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":1385,"title":1386},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites\u002Fi18n-routing-in-astro","i18n Routing in Astro",{"path":1388,"title":1389},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites","Internationalization for Static Sites",{"path":1391,"title":1392},"\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":1394,"title":1395},"\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":1397,"title":1398},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites\u002Fmultilingual-sites-with-hugo","Multilingual Sites with Hugo",{"path":1400,"title":1401},"\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":1403,"title":1404},"\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":1406,"title":1407},"\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":1409,"title":1410},"\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":1412,"title":1413},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fdeploying-jekyll-with-github-actions","Deploying Jekyll with GitHub Actions",{"path":1415,"title":1416},"\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":1418,"title":1419},"\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":1421,"title":1422},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem","Jekyll Plugin Ecosystem",{"path":1424,"title":1425},"\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":1427,"title":1428},"\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":1430,"title":1431},"\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":1433,"title":1434},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fspeeding-up-slow-jekyll-builds","Speeding Up Slow Jekyll Builds",{"path":1436,"title":1437},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fupgrading-jekyll-and-ruby-versions-safely","Upgrading Jekyll and Ruby Versions Safely",{"path":1439,"title":1440},"\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":1442,"title":1443},"\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":1445,"title":1446},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators","Migrating Between Static Site Generators",{"path":1448,"title":857},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fkeeping-redirects-working-after-an-ssg-migration",{"path":1450,"title":1451},"\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":1453,"title":1454},"\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":1456,"title":1457},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-from-docusaurus-to-starlight","Migrating from Docusaurus to Starlight",{"path":1459,"title":1460},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-from-gatsby-to-astro","Migrating from Gatsby to Astro",{"path":1462,"title":1463},"\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":1465,"title":1466},"\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":1468,"title":1469},"\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":1471,"title":1472},"\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":1474,"title":1475},"\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":1477,"title":1478},"\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":1480,"title":1481},"\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":1483,"title":1484},"\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":1486,"title":1487},"\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":1489,"title":1490},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites","Next.js Static Export for Content Sites",{"path":1492,"title":1493},"\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":1495,"title":1496},"\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":1498,"title":1499},"\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":1501,"title":1502},"\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":1504,"title":1505},"\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":1507,"title":1508},"\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":1510,"title":1511},"\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":1513,"title":1514},"\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":1516,"title":1517},"\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":1519,"title":1520},"\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":1522,"title":1523},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fcustomizing-the-pagefind-ui","Customizing the Pagefind UI",{"path":1525,"title":1526},"\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":1528,"title":1529},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites","Search for Static Sites",{"path":1531,"title":1532},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Findexing-hugo-sites-with-pagefind","Indexing Hugo Sites with Pagefind",{"path":1534,"title":1535},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fmultilingual-search-on-static-sites","Multilingual Search on Static Sites",{"path":1537,"title":1538},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fpagefind-vs-algolia-docsearch","Pagefind vs Algolia DocSearch",{"path":1540,"title":1541},"\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":1543,"title":1544},"\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":1546,"title":1547},"\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":1549,"title":1550},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Ftracking-zero-result-searches","Tracking Zero-Result Searches",{"path":1552,"title":1553},"\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":1555,"title":1556},"\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":1558,"title":1559},"\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":1561,"title":1562},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fevaluating-ssg-accessibility-defaults","Evaluating SSG Accessibility Defaults",{"path":1564,"title":1565},"\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":1567,"title":1568},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix","SSG Framework Selection Matrix",{"path":1570,"title":1571},"\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":1573,"title":1574},"\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":1576,"title":1577},"\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":1579,"title":1580},"\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":1582,"title":1583},"\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":1585,"title":1586},"\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":1588,"title":1589},"\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":1591,"title":1592},"\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":1594,"title":1595},"\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":1597,"title":1598},"\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":1600,"title":1601},"\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":1603,"title":1604},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Ftechnical-seo-for-static-sites","Technical SEO for Static Sites",{"path":1606,"title":1607},"\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":1609,"title":1610},"\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":1612,"title":1613},"\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":1615,"title":1616},"\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":1618,"title":1619},"\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":1621,"title":1622},"\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":1624,"title":1625},"\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":1627,"title":1628},"\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":1630,"title":1631},"\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":1633,"title":1634},"\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":1636,"title":1637},"\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":1639,"title":1640},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs","CDN Caching Rules for SSGs",{"path":1642,"title":1643},"\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":1645,"title":1646},"\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":1648,"title":1649},"\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":1651,"title":1652},"\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":1654,"title":1655},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Ftiered-caching-and-origin-shield","Tiered Caching and Origin Shield",{"path":1657,"title":1658},"\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":1660,"title":1661},"\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":1663,"title":1664},"\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":1666,"title":1667},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcss-and-javascript-asset-optimization","CSS and JavaScript Asset Optimization",{"path":1669,"title":1670},"\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":1672,"title":1673},"\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":1675,"title":1676},"\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":1678,"title":1679},"\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":1681,"title":1682},"\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":1684,"title":1685},"\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":1687,"title":1688},"\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":1690,"title":1691},"\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":1693,"title":1694},"\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":1696,"title":1697},"\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":1699,"title":1700},"\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":1702,"title":1703},"\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":1705,"title":1706},"\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":1708,"title":1709},"\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":1711,"title":1712},"\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":1714,"title":1715},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites","Cumulative Layout Shift Fixes for Static Sites",{"path":1717,"title":1718},"\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":1720,"title":1721},"\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":1723,"title":1724},"\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":1726,"title":1727},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fauditing-font-payload-per-page","Auditing Font Payload per Page",{"path":1729,"title":1730},"\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":1732,"title":1733},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Ffont-display-optional-vs-swap","font-display: optional vs swap",{"path":1735,"title":1736},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites","Font Loading Strategies for Static Sites",{"path":1738,"title":1739},"\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":1741,"title":1742},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fpreloading-fonts-without-double-downloads","Preloading Fonts Without Double Downloads",{"path":1744,"title":1745},"\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":1747,"title":1748},"\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":1750,"title":1751},"\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":1753,"title":1754},"\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":1756,"title":1757},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fvariable-fonts-vs-static-weights","Variable Fonts vs Static Weights",{"path":1759,"title":1760},"\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":1762,"title":1763},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fblur-up-placeholders-with-lqip","Blur-Up Placeholders with LQIP",{"path":1765,"title":1766},"\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":1768,"title":1769},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fcaching-processed-images-between-builds","Caching Processed Images Between Builds",{"path":1771,"title":1772},"\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":1774,"title":1775},"\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":1777,"title":1778},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro","Image Optimization Pipelines in Astro",{"path":1780,"title":1781},"\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":1783,"title":1784},"\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":1786,"title":1787},"\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":1789,"title":1790},"\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":1792,"title":1793},"\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":1795,"title":1796},"\u002Fperformance-optimization-core-web-vitals-for-ssgs","Core Web Vitals Optimization for SSGs",{"path":1798,"title":1799},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fastro-islands-vs-full-hydration-performance","Astro Islands vs Full Hydration Performance",{"path":1801,"title":1802},"\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":1804,"title":1805},"\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":1807,"title":1808},"\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":1810,"title":1811},"\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":1813,"title":1814},"\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":1816,"title":1817},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering","JavaScript Hydration & Partial Rendering",{"path":1819,"title":1820},"\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":1822,"title":1823},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fpreact-vs-react-islands-bundle-size","Preact vs React Islands Bundle Size",{"path":1825,"title":1826},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Freplacing-react-islands-with-web-components","Replacing React Islands with Web Components",{"path":1828,"title":1829},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fserver-islands-in-astro","Server Islands in Astro",{"path":1831,"title":1832},"\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":1834,"title":1835},"\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":1837,"title":1838},"\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":1840,"title":1841},"\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":1843,"title":1844},"\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":1846,"title":1847},"\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":1849,"title":1850},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites","Largest Contentful Paint Optimization for Static Sites",{"path":1852,"title":1853},"\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":1855,"title":1856},"\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":1858,"title":1859},"\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":1861,"title":1862},"\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":1864,"title":1865},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci","Performance Budgets and Lighthouse CI",{"path":1867,"title":1868},"\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":1870,"title":1871},"\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":1873,"title":1874},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fper-template-performance-budgets","Per-Template Performance Budgets",{"path":1876,"title":1877},"\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":1879,"title":1880},"\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":1882,"title":1883},"\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":1885,"title":1886},"\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":1888,"title":1889},"\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":1891,"title":1892},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Ftracking-page-weight-over-time","Tracking Page Weight Over Time",{"path":1894,"title":1895},"\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":1897,"title":1898},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fauditing-unused-preloads","Auditing Unused Preloads",{"path":1900,"title":1901},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fearly-hints-103-on-cloudflare","Early Hints (103) on Cloudflare",{"path":1903,"title":1904},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Ffetchpriority-beyond-the-hero-image","Fetchpriority Beyond the Hero Image",{"path":1906,"title":1907},"\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":1909,"title":1910},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed","Resource Hints and Navigation Speed",{"path":1912,"title":1913},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Finstant-navigation-with-speculation-rules","Instant Navigation with Speculation Rules",{"path":1915,"title":1916},"\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":1918,"title":1919},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fprefetching-links-in-astro","Prefetching Links in Astro",{"path":1921,"title":1922},"\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":1924,"title":1925},"\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":1927,"title":1928},"\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":1930,"title":1931},"\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":1933,"title":1934},"\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":1936,"title":1937},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites","Third-Party Script Performance on Static Sites",{"path":1939,"title":1940},"\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":1942,"title":1943},"\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":1945,"title":1946},"\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":1948,"title":1949},"\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":1951,"title":1952},"\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":1954,"title":1955},"\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":1957,"title":1958},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fautomating-eleventy-deployments-with-cloudflare-pages","Automating Eleventy Deployments on Cloudflare Pages",{"path":1960,"title":1961},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fbranch-deploy-controls-on-cloudflare-pages","Branch Deploy Controls on Cloudflare Pages",{"path":1963,"title":1964},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fcloudflare-pages-functions-middleware","Cloudflare Pages Functions Middleware",{"path":1966,"title":44},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fconfiguring-redirects-on-cloudflare-pages",{"path":1968,"title":1969},"\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":1971,"title":1972},"\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":1974,"title":1975},"\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":1977,"title":1978},"\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":1980,"title":1981},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Ffixing-redirect-loops-on-cloudflare-pages","Fixing Redirect Loops on Cloudflare Pages",{"path":1983,"title":1984},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup","Cloudflare Pages Edge Caching Setup",{"path":1986,"title":1987},"\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":1989,"title":1990},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fchecking-links-in-pull-requests","Checking Links in Pull Requests",{"path":1992,"title":1993},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fcontent-linting-with-markdownlint","Content Linting with markdownlint",{"path":1995,"title":1996},"\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":1998,"title":1999},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Feditorial-checks-with-vale-in-ci","Editorial Checks with Vale in CI",{"path":2001,"title":2002},"\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":2004,"title":2005},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams","Content Workflows for Documentation Teams",{"path":2007,"title":2008},"\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":2010,"title":2011},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Frelease-notes-and-changelogs-from-git","Release Notes and Changelogs from Git",{"path":2013,"title":2014},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fscheduled-content-publishing-with-github-actions","Scheduled Content Publishing With GitHub Actions",{"path":2016,"title":2017},"\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":2019,"title":2020},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fwiring-a-headless-cms-to-a-static-build","Wiring a Headless CMS to a Static Build",{"path":2022,"title":2023},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fbuilding-astro-sites-with-github-actions","Building Astro Sites with GitHub Actions",{"path":2025,"title":2026},"\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":2028,"title":2029},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fconcurrency-groups-to-cancel-stale-builds","Concurrency Groups to Cancel Stale Builds",{"path":2031,"title":2032},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fdeploying-to-github-pages-with-actions","Deploying to GitHub Pages with Actions",{"path":2034,"title":2035},"\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":2037,"title":2038},"\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":2040,"title":2041},"\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":2043,"title":2044},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds","GitHub Actions for Automated SSG Builds",{"path":2046,"title":2047},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fmatrix-builds-for-multi-site-monorepos","Matrix Builds for Multi-Site Monorepos",{"path":2049,"title":2050},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fpinning-actions-by-commit-sha","Pinning Actions by Commit SHA",{"path":2052,"title":2053},"\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":2055,"title":2056},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Freusable-workflows-for-ssg-builds","Reusable Workflows for SSG Builds",{"path":2058,"title":2059},"\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":2061,"title":2062},"\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":2064,"title":2065},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fdeploying-only-changed-files","Deploying Only Changed Files",{"path":2067,"title":2068},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fenabling-incremental-builds-in-eleventy","Enabling Incremental Builds in Eleventy",{"path":2070,"title":2071},"\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":2073,"title":2074},"\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":2076,"title":2077},"\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":2079,"title":2080},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs","Incremental Builds and Build Caching for SSGs",{"path":2082,"title":2083},"\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":2085,"title":2086},"\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":2088,"title":2089},"\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":2091,"title":2092},"\u002Fproduction-ready-deployment-cicd-workflows","Production-Ready Deployment & CI\u002FCD for SSGs",{"path":2094,"title":1166},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Falerting-on-cache-hit-ratio-drops",{"path":2096,"title":2097},"\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":2099,"title":1147},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fcrawling-for-broken-links-on-a-schedule",{"path":2101,"title":2102},"\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":2104,"title":24},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production",{"path":1210,"title":5},{"path":2107,"title":2108},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fmonitoring-tls-certificate-expiry","Monitoring TLS Certificate Expiry",{"path":2110,"title":2111},"\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":2113,"title":2114},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fsynthetic-monitoring-with-scheduled-playwright-checks","Synthetic Monitoring With Scheduled Playwright Checks",{"path":2116,"title":2117},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Ftracking-deploy-markers-in-analytics","Tracking Deploy Markers in Analytics",{"path":2119,"title":2120},"\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":2122,"title":2123},"\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":2125,"title":2126},"\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":2128,"title":2129},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fconfiguring-vercel-for-hugo-and-eleventy","Configuring Vercel for Hugo and Eleventy",{"path":2131,"title":2132},"\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":2134,"title":2135},"\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":2137,"title":2138},"\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":2140,"title":2141},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies","Netlify vs Vercel Deployment Strategies",{"path":2143,"title":2144},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-build-hooks-for-content-updates","Netlify Build Hooks for Content Updates",{"path":2146,"title":2147},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-edge-functions-for-static-sites","Netlify Edge Functions for Static Sites",{"path":2149,"title":1159},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-redirects-and-rewrites-for-static-sites",{"path":2151,"title":2152},"\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":2154,"title":2155},"\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":2157,"title":2158},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fvercel-isr-vs-static-generation-for-ssgs","Vercel ISR vs Static Generation for SSGs",{"path":2160,"title":2161},"\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":2163,"title":2164},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fcleaning-up-stale-preview-deployments","Cleaning Up Stale Preview Deployments",{"path":2166,"title":2167},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fcommenting-on-preview-deploys","Commenting on Preview Deploys",{"path":2169,"title":2170},"\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":2172,"title":2173},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests","Preview Environments for Pull Requests",{"path":2175,"title":2176},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpassword-protecting-preview-deployments","Password-Protecting Preview Deployments",{"path":2178,"title":2179},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpreview-deploys-for-monorepos","Preview Deploys for Monorepos",{"path":2181,"title":2182},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpreviewing-headless-cms-drafts","Previewing Headless CMS Drafts",{"path":2184,"title":2185},"\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":2187,"title":2188},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fvisual-regression-testing-on-preview-deploys","Visual Regression Testing on Preview Deploys",{"path":2190,"title":957},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fatomic-deploys-vs-incremental-uploads",{"path":2192,"title":2193},"\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":2195,"title":2196},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fcanary-releases-for-static-sites","Canary Releases for Static Sites",{"path":2198,"title":2199},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Ffeature-flags-on-static-sites","Feature Flags on Static Sites",{"path":2201,"title":2202},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites","Rollbacks and Deploy Safety for Static Sites",{"path":2204,"title":2205},"\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":2207,"title":2208},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fpost-deploy-verification-checklists","Post-Deploy Verification Checklists",{"path":2210,"title":2211},"\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":2213,"title":2214},"\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":2216,"title":2217},"\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":2219,"title":2220},"\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":2222,"title":2223},"\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":2225,"title":2226},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fauditing-npm-dependencies-in-ssg-pipelines","Auditing npm Dependencies in SSG Pipelines",{"path":2228,"title":2229},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fenabling-hsts-and-preload-safely","Enabling HSTS and Preload Safely",{"path":2231,"title":2232},"\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":2234,"title":2235},"\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":2237,"title":2238},"\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":2240,"title":2241},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites","Security Headers and Hardening for Static Sites",{"path":2243,"title":2244},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fpermissions-policy-and-cross-origin-headers","Permissions-Policy and Cross-Origin Headers",{"path":2246,"title":2247},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsecuring-deploy-credentials-with-github-oidc","Securing Deploy Credentials with GitHub OIDC",{"path":2249,"title":2250},"\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":2252,"title":2253},"\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":2255,"title":2256},"\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":2258,"title":2259},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsubresource-integrity-for-third-party-assets","Subresource Integrity for Third-Party Assets",{"path":2261,"title":2262},"\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":2264,"title":2265},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fbrotli-and-gzip-precompression-served-by-nginx","Brotli and Gzip Precompression Served by Nginx",{"path":2267,"title":2268},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fclean-urls-and-trailing-slashes-on-s3","Clean URLs and Trailing Slashes on S3",{"path":2270,"title":49},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fcloudfront-functions-for-redirects",{"path":2272,"title":2273},"\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":2275,"title":2276},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fhosting-on-azure-static-web-apps","Hosting on Azure Static Web Apps",{"path":2278,"title":2279},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites","Self-Hosting Static Sites on S3, Nginx and Caddy",{"path":2281,"title":2282},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fnginx-vs-caddy-for-serving-static-sites","Nginx vs Caddy for Serving Static Sites",{"path":2284,"title":2285},"\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":2287,"title":2288},"\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":2290,"title":2291},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-caddy","Serving a Static Site with Caddy",{"path":2293,"title":2294},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-nginx","Serving a Static Site with Nginx",{"path":2296,"title":2297},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fstatic-hosting-on-google-cloud-storage","Static Hosting on Google Cloud Storage",{"path":2299,"title":2300},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fzero-downtime-deploys-with-symlink-swaps","Zero-Downtime Deploys with Symlink Swaps",{"path":2302,"title":2303},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fadding-a-contact-form-with-cloudflare-workers","Adding a Contact Form with Cloudflare Workers",{"path":2305,"title":2306},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Ffixing-cold-starts-in-netlify-functions-for-forms","Fixing Cold Starts in Netlify Functions for Forms",{"path":2308,"title":2309},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fhandling-form-submissions-on-a-static-site","Handling Form Submissions on a Static Site",{"path":2311,"title":2312},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites","Serverless Functions for Static Sites",{"path":2314,"title":2315},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fnetlify-functions-vs-cloudflare-workers","Netlify Functions vs Cloudflare Workers",{"path":2317,"title":2318},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fnewsletter-signup-with-an-edge-function","Newsletter Signup with an Edge Function",{"path":2320,"title":2321},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fprotecting-a-static-site-behind-authentication","Protecting a Static Site Behind Authentication",{"path":2323,"title":2324},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fproxying-third-party-apis-from-an-edge-function","Proxying Third-Party APIs from an Edge Function",{"path":2326,"title":2327},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Frate-limiting-edge-functions","Rate Limiting Edge Functions",{"path":2329,"title":2330},"\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":2332,"title":2333},"\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":2335,"title":2336},"\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":2338,"title":2339},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci","Testing Static Sites in CI",{"path":2341,"title":2342},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Fsnapshot-testing-build-output","Snapshot Testing Build Output",{"path":2344,"title":2345},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Ftesting-redirects-and-headers-before-deploy","Testing Redirects and Headers Before Deploy",{"path":2347,"title":2348},"\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":2350,"title":2351},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Ftesting-structured-data-and-meta-tags","Testing Structured Data and Meta Tags",{"path":2353,"title":2354},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Fvalidating-html-output-in-ci","Validating HTML Output in CI",{"kind":2356,"tools":2360},{"label":2357,"plural":2358,"u":2359},"How-to","How-tos","\u002Fguides\u002Fhow-to\u002F",[],1790943195930]