[{"data":1,"prerenderedAt":2618},["ShallowReactive",2],{"page:\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites":3,"all-docs-nav":1491,"filed:\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites":2617},{"id":4,"title":5,"body":6,"breadcrumb":1468,"dateModified":1475,"datePublished":1475,"description":1476,"extension":1477,"faq":1478,"meta":1484,"navigation":596,"path":1485,"seo":1486,"slug":1487,"stem":1488,"type":1489,"__hash__":1490},"content\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Findex.md","Self-Hosting Static Sites on S3, Nginx and Caddy",{"type":7,"value":8,"toc":1443},"minimark",[9,13,17,44,191,196,199,409,423,427,430,541,553,557,560,651,673,676,679,686,693,774,778,781,787,811,815,827,925,929,932,938,944,950,957,961,977,981,984,1044,1047,1051,1066,1070,1100,1104,1107,1143,1147,1150,1229,1232,1236,1284,1288,1305,1309,1314,1317,1321,1324,1328,1331,1335,1338,1342,1345,1349,1439],[10,11,5],"h1",{"id":12},"self-hosting-static-sites-on-s3-nginx-and-caddy",[14,15,16],"p",{},"Managed static hosts — Cloudflare Pages, Netlify, Vercel, GitHub Pages — make publishing a folder of HTML almost effortless, and for most sites they are the right answer. But plenty of teams host static sites themselves: a regulated organisation that must keep data in its own cloud account, a company with a large existing AWS contract, a documentation portal behind corporate single sign-on, a site at a traffic level where per-request pricing matters, or simply a team that wants every header, log line and routing rule under its own control.",[14,18,19,20,24,25,28,29,32,33,38,39,43],{},"Self-hosting a static site is not hard, but it means rebuilding the conveniences a managed host provides: clean URLs, redirects, headers, TLS, cache rules, atomic deploys and rollback. This topic covers the three most common setups — ",[21,22,23],"strong",{},"S3 with CloudFront",", ",[21,26,27],{},"nginx on a VM"," and ",[21,30,31],{},"Caddy on a VM"," — and how to rebuild each convenience. It sits inside ",[34,35,37],"a",{"href":36},"\u002Fproduction-ready-deployment-cicd-workflows\u002F","Production-Ready Deployment & CI\u002FCD Workflows",", next to the managed-host comparison in ",[34,40,42],{"href":41},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002F","Netlify vs Vercel Deployment Strategies",".",[45,46,47,187],"figure",{},[48,49,56,57,56,61,56,65,56,72],"svg",{"viewBox":50,"role":51,"ariaLabelledBy":52,"xmlns":55},"0 0 780 320","img",[53,54],"shs2-arch-title","shs2-arch-desc","http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg","\n  ",[58,59,60],"title",{"id":53},"Three self-hosting architectures",[62,63,64],"desc",{"id":54},"Three stacks. S3 plus CloudFront: CI uploads to a private S3 bucket, CloudFront serves it globally with a CloudFront Function for URL rewriting and redirects. Nginx on a VM: CI uploads a release directory over SSH, a symlink points to the current release, nginx serves it, optionally behind a CDN. Caddy on a VM: the same release and symlink layout, with Caddy handling TLS certificates automatically.",[66,67],"rect",{"x":68,"y":68,"width":69,"height":70,"fill":71},"0","780","320","#ffffff",[73,74,76,77,76,85,76,96,76,102,76,111,76,116,76,119,76,123,76,126,76,130,76,136,76,141,76,143,76,146,76,149,76,151,76,154,76,156,76,159,76,162,76,167,76,170,76,173,76,175,76,177,76,179,76,181,76,184,56],"g",{"style":75},"font-family:system-ui, sans-serif;font-size:12px","\n    ",[78,79,84],"text",{"x":80,"y":81,"fill":82,"style":83},"390","28","#1f2937","font-size:16px;font-weight:700;text-anchor:middle","Same static files, three ways to serve them",[66,86],{"x":87,"y":88,"width":89,"height":90,"rx":91,"fill":92,"opacity":93,"stroke":94,"style":95},"30","50","230","250","12","#ffca3a","0.1","#a97b00","stroke-width:1.5px",[78,97,101],{"x":98,"y":99,"fill":82,"style":100},"145","76","font-size:14px;font-weight:700;text-anchor:middle","S3 + CloudFront",[66,103],{"x":88,"y":104,"width":105,"height":106,"rx":107,"fill":108,"stroke":109,"style":110},"94","190","40","8","#f8fafc","#d9e2ef","stroke-width:1px",[78,112,115],{"x":98,"y":113,"fill":82,"style":114},"119","text-anchor:middle","CI: aws s3 sync",[66,117],{"x":88,"y":118,"width":105,"height":106,"rx":107,"fill":108,"stroke":109,"style":110},"146",[78,120,122],{"x":98,"y":121,"fill":82,"style":114},"171","private bucket (OAC)",[66,124],{"x":88,"y":125,"width":105,"height":106,"rx":107,"fill":108,"stroke":109,"style":110},"198",[78,127,129],{"x":98,"y":128,"fill":82,"style":114},"223","CloudFront + Function",[78,131,135],{"x":98,"y":132,"fill":133,"style":134},"270","#556071","font-size:11px;text-anchor:middle","global edge, pay per request",[66,137],{"x":138,"y":88,"width":89,"height":90,"rx":91,"fill":139,"opacity":140,"stroke":139,"style":95},"275","#1982c4","0.08",[78,142,27],{"x":80,"y":99,"fill":82,"style":100},[66,144],{"x":145,"y":104,"width":105,"height":106,"rx":107,"fill":108,"stroke":109,"style":110},"295",[78,147,148],{"x":80,"y":113,"fill":82,"style":114},"CI: rsync release dir",[66,150],{"x":145,"y":118,"width":105,"height":106,"rx":107,"fill":108,"stroke":109,"style":110},[78,152,153],{"x":80,"y":121,"fill":82,"style":114},"current → releases\u002FN",[66,155],{"x":145,"y":125,"width":105,"height":106,"rx":107,"fill":108,"stroke":109,"style":110},[78,157,158],{"x":80,"y":128,"fill":82,"style":114},"nginx (+ certbot)",[78,160,161],{"x":80,"y":132,"fill":133,"style":134},"full control, fixed cost",[66,163],{"x":164,"y":88,"width":89,"height":90,"rx":91,"fill":165,"opacity":93,"stroke":166,"style":95},"520","#8ac926","#5a8a16",[78,168,31],{"x":169,"y":99,"fill":82,"style":100},"635",[66,171],{"x":172,"y":104,"width":105,"height":106,"rx":107,"fill":108,"stroke":109,"style":110},"540",[78,174,148],{"x":169,"y":113,"fill":82,"style":114},[66,176],{"x":172,"y":118,"width":105,"height":106,"rx":107,"fill":108,"stroke":109,"style":110},[78,178,153],{"x":169,"y":121,"fill":82,"style":114},[66,180],{"x":172,"y":125,"width":105,"height":106,"rx":107,"fill":108,"stroke":109,"style":110},[78,182,183],{"x":169,"y":128,"fill":82,"style":114},"Caddy (automatic TLS)",[78,185,186],{"x":169,"y":132,"fill":133,"style":134},"least config, fixed cost",[188,189,190],"figcaption",{},"All three serve the same build output; they differ in how they handle URLs, TLS, caching and deploys.",[192,193,195],"h2",{"id":194},"what-a-managed-host-was-doing-for-you","What a Managed Host Was Doing for You",[14,197,198],{},"Before choosing a stack, list the features you will need to rebuild. Every managed static host provides roughly the same set:",[200,201,202,223],"table",{},[203,204,205],"thead",{},[206,207,208,212,215,217,220],"tr",{},[209,210,211],"th",{},"Feature",[209,213,214],{},"Managed host",[209,216,101],{},[209,218,219],{},"nginx",[209,221,222],{},"Caddy",[224,225,226,243,275,300,323,347,363,379,395],"tbody",{},[206,227,228,232,235,238,241],{},[229,230,231],"td",{},"TLS certificates",[229,233,234],{},"automatic",[229,236,237],{},"ACM, automatic",[229,239,240],{},"certbot, cron",[229,242,234],{},[206,244,245,257,259,262,267],{},[229,246,247,248,252,253,256],{},"Clean URLs (",[249,250,251],"code",{},"\u002Fguide\u002F"," → ",[249,254,255],{},"\u002Fguide\u002Findex.html",")",[229,258,234],{},[229,260,261],{},"CloudFront Function",[229,263,264],{},[249,265,266],{},"try_files",[229,268,269,271,272],{},[249,270,266],{}," \u002F ",[249,273,274],{},"file_server",[206,276,277,280,286,289,295],{},[229,278,279],{},"Redirect rules",[229,281,282,285],{},[249,283,284],{},"_redirects"," file",[229,287,288],{},"CloudFront Function or S3 rules",[229,290,291,294],{},[249,292,293],{},"return 301"," \u002F map",[229,296,297],{},[249,298,299],{},"redir",[206,301,302,305,310,313,318],{},[229,303,304],{},"Custom headers",[229,306,307,285],{},[249,308,309],{},"_headers",[229,311,312],{},"response headers policy",[229,314,315],{},[249,316,317],{},"add_header",[229,319,320],{},[249,321,322],{},"header",[206,324,325,328,330,333,342],{},[229,326,327],{},"Compression",[229,329,234],{},[229,331,332],{},"CloudFront setting",[229,334,335,24,338,341],{},[249,336,337],{},"gzip",[249,339,340],{},"brotli"," module",[229,343,344],{},[249,345,346],{},"encode zstd gzip",[206,348,349,352,355,358,361],{},[229,350,351],{},"Atomic deploy",[229,353,354],{},"built in",[229,356,357],{},"upload order or origin path switch",[229,359,360],{},"symlink swap",[229,362,360],{},[206,364,365,368,371,374,377],{},[229,366,367],{},"Instant rollback",[229,369,370],{},"one click",[229,372,373],{},"re-point or re-sync",[229,375,376],{},"symlink back",[229,378,376],{},[206,380,381,384,387,390,393],{},[229,382,383],{},"Preview deploys",[229,385,386],{},"per PR",[229,388,389],{},"prefix per PR",[229,391,392],{},"subdomain per PR",[229,394,392],{},[206,396,397,400,402,404,407],{},[229,398,399],{},"Global edge",[229,401,354],{},[229,403,354],{},[229,405,406],{},"add a CDN",[229,408,406],{},[14,410,411,412,414,415,417,418,422],{},"The clean-URL row trips up more S3 deployments than any other. S3's REST endpoint does not resolve ",[249,413,251],{}," to ",[249,416,255],{},"; without a rewrite, every directory-style URL returns an XML error. ",[34,419,421],{"href":420},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fclean-urls-and-trailing-slashes-on-s3\u002F","Clean URLs and Trailing Slashes on S3"," covers the fix.",[192,424,426],{"id":425},"s3-and-cloudfront","S3 and CloudFront",[14,428,429],{},"For AWS-centric organisations this is the default. The bucket stays private; CloudFront reads it through Origin Access Control, serves from over 400 edge locations, terminates TLS with a free ACM certificate, and runs small CloudFront Functions on each request for URL rewriting and redirects.",[431,432,437],"pre",{"className":433,"code":434,"language":435,"meta":436,"style":436},"language-bash shiki shiki-themes github-light github-dark","aws s3 sync dist\u002F s3:\u002F\u002Fdocs-example-com\u002F --delete \\\n  --exclude '*.html' --cache-control 'public, max-age=31536000, immutable'\naws s3 sync dist\u002F s3:\u002F\u002Fdocs-example-com\u002F --delete \\\n  --exclude '*' --include '*.html' --cache-control 'public, max-age=0, must-revalidate'\naws cloudfront create-invalidation --distribution-id E2ABC123 --paths '\u002F*'\n","bash","",[249,438,439,468,483,500,518],{"__ignoreMap":436},[440,441,444,448,452,455,458,461,465],"span",{"class":442,"line":443},"line",1,[440,445,447],{"class":446},"sScJk","aws",[440,449,451],{"class":450},"sZZnC"," s3",[440,453,454],{"class":450}," sync",[440,456,457],{"class":450}," dist\u002F",[440,459,460],{"class":450}," s3:\u002F\u002Fdocs-example-com\u002F",[440,462,464],{"class":463},"sj4cs"," --delete",[440,466,467],{"class":463}," \\\n",[440,469,471,474,477,480],{"class":442,"line":470},2,[440,472,473],{"class":463},"  --exclude",[440,475,476],{"class":450}," '*.html'",[440,478,479],{"class":463}," --cache-control",[440,481,482],{"class":450}," 'public, max-age=31536000, immutable'\n",[440,484,486,488,490,492,494,496,498],{"class":442,"line":485},3,[440,487,447],{"class":446},[440,489,451],{"class":450},[440,491,454],{"class":450},[440,493,457],{"class":450},[440,495,460],{"class":450},[440,497,464],{"class":463},[440,499,467],{"class":463},[440,501,503,505,508,511,513,515],{"class":442,"line":502},4,[440,504,473],{"class":463},[440,506,507],{"class":450}," '*'",[440,509,510],{"class":463}," --include",[440,512,476],{"class":450},[440,514,479],{"class":463},[440,516,517],{"class":450}," 'public, max-age=0, must-revalidate'\n",[440,519,521,523,526,529,532,535,538],{"class":442,"line":520},5,[440,522,447],{"class":446},[440,524,525],{"class":450}," cloudfront",[440,527,528],{"class":450}," create-invalidation",[440,530,531],{"class":463}," --distribution-id",[440,533,534],{"class":450}," E2ABC123",[440,536,537],{"class":463}," --paths",[440,539,540],{"class":450}," '\u002F*'\n",[14,542,543,544,548,549,43],{},"Two uploads with different cache headers, assets first and HTML last, keep pages consistent during the deploy: new HTML never references an asset that has not been uploaded yet. The full setup is in ",[34,545,547],{"href":546},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fdeploying-a-static-site-to-s3-and-cloudfront\u002F","Deploying a Static Site to S3 and CloudFront",", and redirect handling in ",[34,550,552],{"href":551},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fcloudfront-functions-for-redirects\u002F","CloudFront Functions for Redirects",[192,554,556],{"id":555},"nginx-on-a-vm","Nginx on a VM",[14,558,559],{},"Nginx is fast, universally understood and gives complete control. A static site needs very little of it:",[431,561,564],{"className":562,"code":563,"language":219,"meta":436,"style":436},"language-nginx shiki shiki-themes github-light github-dark","server {\n  listen 443 ssl http2;\n  server_name docs.example.com;\n  root \u002Fsrv\u002Fdocs\u002Fcurrent;\n  include \u002Fetc\u002Fnginx\u002Fsnippets\u002Fsecurity-headers.conf;\n\n  location \u002F {\n    try_files $uri $uri\u002Findex.html $uri.html =404;\n  }\n  location \u002F_astro\u002F {\n    include \u002Fetc\u002Fnginx\u002Fsnippets\u002Fsecurity-headers.conf;\n    add_header Cache-Control \"public, max-age=31536000, immutable\";\n  }\n  error_page 404 \u002F404.html;\n}\n",[249,565,566,571,576,581,586,591,598,604,610,616,622,628,634,639,645],{"__ignoreMap":436},[440,567,568],{"class":442,"line":443},[440,569,570],{},"server {\n",[440,572,573],{"class":442,"line":470},[440,574,575],{},"  listen 443 ssl http2;\n",[440,577,578],{"class":442,"line":485},[440,579,580],{},"  server_name docs.example.com;\n",[440,582,583],{"class":442,"line":502},[440,584,585],{},"  root \u002Fsrv\u002Fdocs\u002Fcurrent;\n",[440,587,588],{"class":442,"line":520},[440,589,590],{},"  include \u002Fetc\u002Fnginx\u002Fsnippets\u002Fsecurity-headers.conf;\n",[440,592,594],{"class":442,"line":593},6,[440,595,597],{"emptyLinePlaceholder":596},true,"\n",[440,599,601],{"class":442,"line":600},7,[440,602,603],{},"  location \u002F {\n",[440,605,607],{"class":442,"line":606},8,[440,608,609],{},"    try_files $uri $uri\u002Findex.html $uri.html =404;\n",[440,611,613],{"class":442,"line":612},9,[440,614,615],{},"  }\n",[440,617,619],{"class":442,"line":618},10,[440,620,621],{},"  location \u002F_astro\u002F {\n",[440,623,625],{"class":442,"line":624},11,[440,626,627],{},"    include \u002Fetc\u002Fnginx\u002Fsnippets\u002Fsecurity-headers.conf;\n",[440,629,631],{"class":442,"line":630},12,[440,632,633],{},"    add_header Cache-Control \"public, max-age=31536000, immutable\";\n",[440,635,637],{"class":442,"line":636},13,[440,638,615],{},[440,640,642],{"class":442,"line":641},14,[440,643,644],{},"  error_page 404 \u002F404.html;\n",[440,646,648],{"class":442,"line":647},15,[440,649,650],{},"}\n",[14,652,653,654,657,658,661,662,664,665,668,669,43],{},"The ",[249,655,656],{},"include"," inside the ",[249,659,660],{},"location"," block is not redundant: nginx's ",[249,663,317],{}," directives in a nested block replace those from the parent rather than adding to them, so a location that sets ",[249,666,667],{},"Cache-Control"," loses every security header unless they are repeated. It is the most common self-hosting mistake, and it is invisible until someone checks the headers on an asset. The complete configuration is in ",[34,670,672],{"href":671},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-nginx\u002F","Serving a Static Site with Nginx",[192,674,31],{"id":675},"caddy-on-a-vm",[14,677,678],{},"Caddy does less configuration for the same result. It obtains and renews TLS certificates automatically, redirects HTTP to HTTPS, and enables modern protocols by default:",[431,680,684],{"className":681,"code":683,"language":78,"meta":436},[682],"language-text","docs.example.com {\n  root * \u002Fsrv\u002Fdocs\u002Fcurrent\n  encode zstd gzip\n  try_files {path} {path}\u002Findex.html {path}.html\n  file_server\n  header \u002F_astro\u002F* Cache-Control \"public, max-age=31536000, immutable\"\n  import security_headers\n  handle_errors {\n    rewrite * \u002F404.html\n    file_server\n  }\n}\n",[249,685,683],{"__ignoreMap":436},[14,687,688,689,43],{},"For a single team running a handful of static sites on one VM, Caddy is the lowest-maintenance option available. See ",[34,690,692],{"href":691},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-caddy\u002F","Serving a Static Site with Caddy",[45,694,695,771],{},[48,696,56,701,56,704,56,707,56,710],{"viewBox":697,"role":51,"ariaLabelledBy":698,"xmlns":55},"0 0 780 290",[699,700],"shs2-cfg-title","shs2-cfg-desc",[58,702,703],{"id":699},"Configuration effort for the same feature set",[62,705,706],{"id":700},"Bars of lines of configuration needed for TLS, clean URLs, redirects, headers, compression and caching. Caddy needed about 20 lines. Nginx needed about 70 lines plus a certbot timer. S3 plus CloudFront needed about 110 lines of Terraform plus a 40-line CloudFront Function.",[66,708],{"x":68,"y":68,"width":69,"height":709,"fill":71},"290",[73,711,76,712,76,715,76,720,76,724,76,730,76,734,76,737,76,742,76,746,76,749,76,753,76,758,76,763,76,767,56],{"style":75},[78,713,714],{"x":80,"y":81,"fill":82,"style":83},"Lines of configuration for the same features",[442,716],{"x1":717,"y1":718,"x2":717,"y2":719,"stroke":109,"style":95},"220","46","236",[78,721,222],{"x":106,"y":722,"fill":82,"style":723},"84","font-weight:700",[66,725],{"x":717,"y":726,"width":727,"height":81,"rx":728,"fill":165,"opacity":729,"stroke":166,"style":110},"66","60","4","0.35",[78,731,733],{"x":709,"y":732,"fill":82},"85","~20 lines",[78,735,219],{"x":106,"y":736,"fill":82,"style":723},"144",[66,738],{"x":717,"y":739,"width":740,"height":81,"rx":728,"fill":139,"opacity":741,"stroke":139,"style":110},"126","210","0.25",[78,743,745],{"x":744,"y":98,"fill":82},"440","~70 lines + certbot timer",[78,747,101],{"x":106,"y":748,"fill":82,"style":723},"204",[66,750],{"x":717,"y":751,"width":752,"height":81,"rx":728,"fill":92,"opacity":729,"stroke":94,"style":110},"186","330",[66,754],{"x":755,"y":751,"width":756,"height":81,"rx":728,"fill":92,"opacity":757,"stroke":94,"style":110},"550","120","0.2",[78,759,762],{"x":760,"y":761,"fill":82,"style":114},"385","205","~110 lines Terraform",[78,764,766],{"x":765,"y":761,"fill":82,"style":134},"610","+ 40-line Function",[78,768,770],{"x":80,"y":769,"fill":133,"style":134},"266","TLS, clean URLs, 25 redirects, security headers, compression, two cache tiers",[188,772,773],{},"More configuration buys more scale: S3 and CloudFront take the most setup and need the least operating afterwards at high traffic.",[192,775,777],{"id":776},"atomic-deploys-and-rollback-without-a-managed-host","Atomic Deploys and Rollback Without a Managed Host",[14,779,780],{},"A managed host swaps the whole site at once and keeps previous deploys for instant rollback. On a VM, the equivalent is a release directory per deploy and a symlink that points to the current one:",[431,782,785],{"className":783,"code":784,"language":78,"meta":436},[682],"\u002Fsrv\u002Fdocs\u002F\n├── releases\u002F\n│   ├── 20260915-1412-a1b2c3d\u002F\n│   ├── 20260917-0931-e4f5a6b\u002F\n│   └── 20260918-1106-c7d8e9f\u002F\n└── current -> releases\u002F20260918-1106-c7d8e9f\n",[249,786,784],{"__ignoreMap":436},[14,788,789,790,793,794,797,798,801,802,806,807,810],{},"CI uploads a new release directory with ",[249,791,792],{},"rsync",", then replaces the symlink with ",[249,795,796],{},"ln -sfn"," followed by an atomic ",[249,799,800],{},"mv -T",". Every request sees either the whole old site or the whole new one. Rolling back is re-pointing the symlink at the previous directory — under a second. ",[34,803,805],{"href":804},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fzero-downtime-deploys-with-symlink-swaps\u002F","Zero-Downtime Deploys with Symlink Swaps"," has the script and the retention policy. On S3, the equivalent is uploading to a versioned prefix (",[249,808,809],{},"\u002Freleases\u002Fc7d8e9f\u002F",") and changing the CloudFront origin path, or relying on upload ordering as shown above.",[192,812,814],{"id":813},"caching-in-front-of-a-vm","Caching in Front of a VM",[14,816,817,818,821,822,826],{},"A single VM in one region serves readers on other continents slowly: from a Frankfurt VM, time to first byte measured 38 ms from Berlin, 160 ms from New York and 310 ms from Sydney. A CDN in front removes most of that. Cloudflare's free plan or CloudFront with the VM as a custom origin both work. The cache policy is the same one used for managed hosts — long ",[249,819,820],{},"immutable"," lifetimes for hashed assets, short or revalidating lifetimes for HTML — described in ",[34,823,825],{"href":824},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002F","CDN Caching Rules for SSGs",". With the CDN in place, the VM mostly serves cache revalidations and can be very small.",[45,828,829,922],{},[48,830,56,835,56,838,56,841,56,843],{"viewBox":831,"role":51,"ariaLabelledBy":832,"xmlns":55},"0 0 780 270",[833,834],"shs2-ttfb-title","shs2-ttfb-desc",[58,836,837],{"id":833},"Time to first byte by reader location",[62,839,840],{"id":834},"Paired bars for three cities. From Berlin, a Frankfurt VM alone gives 38 milliseconds and with a CDN 22. From New York, 160 alone and 29 with a CDN. From Sydney, 310 alone and 34 with a CDN.",[66,842],{"x":68,"y":68,"width":69,"height":132,"fill":71},[73,844,76,845,76,848,76,852,76,856,76,863,76,868,76,871,76,878,76,882,76,886,76,891,76,894,76,898,76,902,76,906,76,911,76,914,76,918,56],{"style":75},[78,846,847],{"x":80,"y":81,"fill":82,"style":83},"TTFB for a cached HTML page, Frankfurt VM (ms)",[442,849],{"x1":850,"y1":718,"x2":850,"y2":851,"stroke":109,"style":95},"170","226",[78,853,855],{"x":106,"y":854,"fill":82,"style":723},"80","Berlin",[66,857],{"x":850,"y":858,"width":859,"height":860,"rx":861,"fill":139,"opacity":862,"stroke":139,"style":110},"62","68","18","3","0.3",[78,864,867],{"x":865,"y":99,"fill":82,"style":866},"246","font-size:11px","38 VM only",[66,869],{"x":850,"y":722,"width":106,"height":860,"rx":861,"fill":165,"opacity":870,"stroke":166,"style":110},"0.4",[78,872,877],{"x":873,"y":874,"fill":875,"style":876},"218","98","#3f6410","font-size:11px;font-weight:700","22 with CDN",[78,879,881],{"x":106,"y":880,"fill":82,"style":723},"140","New York",[66,883],{"x":850,"y":884,"width":885,"height":860,"rx":861,"fill":139,"opacity":862,"stroke":139,"style":110},"122","288",[78,887,890],{"x":888,"y":889,"fill":82,"style":866},"466","136","160 VM only",[66,892],{"x":850,"y":736,"width":893,"height":860,"rx":861,"fill":165,"opacity":870,"stroke":166,"style":110},"52",[78,895,897],{"x":89,"y":896,"fill":875,"style":876},"158","29 with CDN",[78,899,901],{"x":106,"y":900,"fill":82,"style":723},"200","Sydney",[66,903],{"x":850,"y":904,"width":905,"height":860,"rx":861,"fill":139,"opacity":862,"stroke":139,"style":110},"182","558",[78,907,910],{"x":908,"y":909,"fill":82,"style":866},"600","196","310 VM only",[66,912],{"x":850,"y":748,"width":913,"height":860,"rx":861,"fill":165,"opacity":870,"stroke":166,"style":110},"61",[78,915,917],{"x":916,"y":873,"fill":875,"style":876},"239","34 with CDN",[78,919,921],{"x":80,"y":920,"fill":133,"style":134},"254","WebPageTest, median of 5, HTML cached at the edge with stale-while-revalidate",[188,923,924],{},"Distance dominates TTFB without a CDN; with one, every city lands within a few milliseconds of the others.",[192,926,928],{"id":927},"choosing-between-the-three","Choosing Between the Three",[14,930,931],{},"The table of features is the same for all three stacks, so the choice comes down to who operates it and at what scale.",[14,933,934,937],{},[21,935,936],{},"Choose S3 and CloudFront"," when the organisation already runs on AWS, when traffic is high or spiky, or when compliance requires the content to stay inside a specific cloud account with IAM-controlled access and CloudTrail logging. There is no server to patch, capacity is effectively unlimited, and everything can be described in Terraform. The costs are setup complexity — URL rewriting and redirects need a CloudFront Function — and slightly slower deploys because of cache invalidation.",[14,939,940,943],{},[21,941,942],{},"Choose nginx"," when you already operate nginx elsewhere, need fine-grained control over request handling (complex redirect maps, authentication subrequests, logging formats), or are putting the static site next to other services on the same host. Its configuration language is widely known, which matters when the person on call at 2 a.m. is not the person who wrote it.",[14,945,946,949],{},[21,947,948],{},"Choose Caddy"," for the smallest operational footprint on a VM: one binary, automatic HTTPS with renewal, sensible defaults, and a config file a newcomer can read in a minute. It is the natural choice for internal documentation portals, staging mirrors and small teams without dedicated infrastructure staff.",[14,951,952,953,956],{},"Whatever the choice, keep the build output identical across hosts. A site that builds the same ",[249,954,955],{},"dist\u002F"," folder for Cloudflare Pages, S3 and a VM can move between them in an afternoon, and a disaster-recovery plan can be as simple as a second deploy target.",[192,958,960],{"id":959},"security-on-self-hosted-stacks","Security on Self-Hosted Stacks",[14,962,963,964,968,969,972,973,976],{},"A managed host hardens the server layer for you; self-hosting hands that job back. For S3, the essentials are a bucket with Block Public Access enabled, Origin Access Control so only CloudFront can read it, and a deploy role limited to that one bucket and distribution. For a VM, they are key-only SSH, a firewall allowing only ports 22 (ideally restricted by source address), 80 and 443, unattended security updates, and a deploy user that can write to the releases directory and nothing else. On all three stacks, the security header set from ",[34,965,967],{"href":966},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002F","Security Headers and Hardening for Static Sites"," applies unchanged — only the syntax differs. Directory listing must be off (it is by default in nginx and Caddy), and dotfiles such as a stray ",[249,970,971],{},".env"," or ",[249,974,975],{},".git"," folder copied into the build output must be denied explicitly, because the server will otherwise serve anything in the web root.",[192,978,980],{"id":979},"cost-at-different-traffic-levels","Cost at Different Traffic Levels",[14,982,983],{},"Self-hosting is sometimes chosen for cost, and the answer depends heavily on traffic. Monthly estimates for a 2,000-page docs site averaging 350 KB per page view, in USD at list prices:",[200,985,986,1001],{},[203,987,988],{},[206,989,990,993,996,998],{},[209,991,992],{},"Monthly page views",[209,994,995],{},"Managed host (free\u002Fpro tier)",[209,997,101],{},[209,999,1000],{},"VM + CDN (free CDN tier)",[224,1002,1003,1016,1030],{},[206,1004,1005,1008,1010,1013],{},[229,1006,1007],{},"100,000",[229,1009,68],{},[229,1011,1012],{},"~4",[229,1014,1015],{},"~6 (smallest VM)",[206,1017,1018,1021,1024,1027],{},[229,1019,1020],{},"1,000,000",[229,1022,1023],{},"0–20",[229,1025,1026],{},"~35",[229,1028,1029],{},"~6",[206,1031,1032,1035,1038,1041],{},[229,1033,1034],{},"10,000,000",[229,1036,1037],{},"20–plan limits",[229,1039,1040],{},"~310",[229,1042,1043],{},"~12 (larger VM)",[14,1045,1046],{},"The numbers above are estimates that move with provider pricing, but the shape is stable: managed hosts are cheapest at small and medium scale, S3 and CloudFront scale linearly with requests and bytes, and a VM behind a free CDN tier is nearly flat. Engineering time usually outweighs all three.",[192,1048,1050],{"id":1049},"logs-and-observability","Logs and Observability",[14,1052,1053,1054,1056,1057,28,1061,1065],{},"One genuine advantage of self-hosting is complete access to request logs. Managed hosts expose limited analytics; your own stack can keep every request. CloudFront standard logs (or real-time logs to Kinesis) and nginx or Caddy access logs record path, status, bytes, cache status and user agent for every hit. Three reports built from them pay for themselves quickly: 404s by path and referrer, which reveal broken links and missing redirects after a migration; cache hit ratio by path prefix, which catches a mis-set ",[249,1055,667],{}," header before it becomes an origin bill; and top user agents by request volume, which separates aggressive crawlers from readers. Keep logs for thirty to ninety days and ship them somewhere queryable — Athena over S3 for CloudFront, or a lightweight pipeline such as Vector into ClickHouse or Loki for a VM. The reports themselves are described in ",[34,1058,1060],{"href":1059},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Flogging-404s-at-the-edge\u002F","Logging 404s at the Edge",[34,1062,1064],{"href":1063},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Falerting-on-cache-hit-ratio-drops\u002F","Alerting on Cache Hit Ratio Drops",". Mind privacy: IP addresses in access logs are personal data in many jurisdictions, so truncate or hash them at ingestion if you do not need them.",[192,1067,1069],{"id":1068},"previews-and-ci","Previews and CI",[14,1071,1072,1073,1076,1077,1080,1081,1084,1085,1089,1090,972,1093,1095,1096,43],{},"Self-hosting does not have to mean giving up preview deploys. On S3, deploy each pull request to a ",[249,1074,1075],{},"pr-123\u002F"," prefix served by a preview distribution; on a VM, deploy to ",[249,1078,1079],{},"\u002Fsrv\u002Fpreviews\u002Fpr-123\u002F"," and serve ",[249,1082,1083],{},"pr-123.preview.example.com"," with a wildcard certificate and a single server block that maps the subdomain to the directory. The GitHub Actions wiring is the same as for managed hosts — see ",[34,1086,1088],{"href":1087},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fautomating-preview-deploy-pipelines-with-github-actions\u002F","Automating Preview Deploy Pipelines with GitHub Actions"," — with the upload step swapped for ",[249,1091,1092],{},"aws s3 sync",[249,1094,792],{},". Clean up previews when pull requests close, exactly as described in ",[34,1097,1099],{"href":1098},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fcleaning-up-stale-preview-deployments\u002F","Cleaning Up Stale Preview Deployments",[192,1101,1103],{"id":1102},"operating-it","Operating It",[14,1105,1106],{},"Self-hosting adds operational work that managed hosts hide:",[1108,1109,1110,1117,1123,1133],"ul",{},[1111,1112,1113,1116],"li",{},[21,1114,1115],{},"Certificate renewal."," Caddy and ACM renew automatically; certbot needs a timer and an alert if renewal fails.",[1111,1118,1119,1122],{},[21,1120,1121],{},"OS and server updates."," A VM needs patching. Unattended security upgrades plus a monthly maintenance window cover most of it.",[1111,1124,1125,1128,1129,43],{},[21,1126,1127],{},"Monitoring."," Uptime checks, certificate expiry alerts and disk space on the VM (old releases accumulate). The monitoring section applies directly: ",[34,1130,1132],{"href":1131},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fuptime-and-synthetic-checks-for-static-sites\u002F","Uptime and Synthetic Checks for Static Sites",[1111,1134,1135,1138,1139,43],{},[21,1136,1137],{},"Access."," Deploys should use a dedicated user with write access only to the release directory, and credentials issued per run, as in ",[34,1140,1142],{"href":1141},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsecuring-deploy-credentials-with-github-oidc\u002F","Securing Deploy Credentials with GitHub OIDC",[192,1144,1146],{"id":1145},"measured-impact","Measured Impact",[14,1148,1149],{},"A 2,000-page documentation site moved from a managed host to S3 and CloudFront for compliance reasons. Performance from Lighthouse and RUM; deploy data from CI.",[200,1151,1152,1163],{},[203,1153,1154],{},[206,1155,1156,1159,1161],{},[209,1157,1158],{},"Measure",[209,1160,214],{},[209,1162,101],{},[224,1164,1165,1176,1186,1197,1208,1219],{},[206,1166,1167,1170,1173],{},[229,1168,1169],{},"TTFB p75 (RUM, global)",[229,1171,1172],{},"92 ms",[229,1174,1175],{},"88 ms",[206,1177,1178,1181,1184],{},[229,1179,1180],{},"LCP p75, mobile",[229,1182,1183],{},"1.7 s",[229,1185,1183],{},[206,1187,1188,1191,1194],{},[229,1189,1190],{},"Deploy time (upload + invalidation)",[229,1192,1193],{},"48 s",[229,1195,1196],{},"71 s",[206,1198,1199,1202,1205],{},[229,1200,1201],{},"Rollback time",[229,1203,1204],{},"~10 s (one click)",[229,1206,1207],{},"~40 s (re-point origin path)",[206,1209,1210,1213,1216],{},[229,1211,1212],{},"Setup effort",[229,1214,1215],{},"~1 hour",[229,1217,1218],{},"~3 days including Terraform and Function",[206,1220,1221,1224,1226],{},[229,1222,1223],{},"Monthly cost (~1.2M page views)",[229,1225,68],{},[229,1227,1228],{},"~42 USD",[14,1230,1231],{},"Readers noticed nothing: edge performance was equivalent. The team paid in setup effort, slightly slower deploys and a monthly bill, and gained data residency, IAM-controlled access and CloudTrail audit logs, which were the reasons for the move.",[192,1233,1235],{"id":1234},"common-pitfalls","Common Pitfalls",[1108,1237,1238,1244,1250,1266,1272,1278],{},[1111,1239,1240,1243],{},[21,1241,1242],{},"Public S3 website endpoints."," They serve over HTTP only and expose the bucket. Use a private bucket behind CloudFront with Origin Access Control.",[1111,1245,1246,1249],{},[21,1247,1248],{},"Forgetting clean URLs."," Directory-style links return errors from S3 until a rewrite is added.",[1111,1251,1252,1258,1259,1262,1263,1265],{},[21,1253,1254,1255,1257],{},"nginx ",[249,1256,317],{}," inheritance."," Headers set in ",[249,1260,1261],{},"server"," vanish in any ",[249,1264,660],{}," that sets its own. Use an include file in each block.",[1111,1267,1268,1271],{},[21,1269,1270],{},"One cache lifetime for everything."," Hashed assets want a year; HTML wants revalidation. A single policy is wrong for one of them.",[1111,1273,1274,1277],{},[21,1275,1276],{},"No release retention."," Symlink deploys fill the disk; keep the last ten releases and delete the rest.",[1111,1279,1280,1283],{},[21,1281,1282],{},"Rebuilding previews last."," Losing preview deploys in a migration slows every review; plan them from the start.",[192,1285,1287],{"id":1286},"key-takeaways","Key Takeaways",[1108,1289,1290,1293,1296,1299,1302],{},[1111,1291,1292],{},"Self-hosting means rebuilding what managed hosts provide: TLS, clean URLs, redirects, headers, atomic deploys, rollback and previews.",[1111,1294,1295],{},"Caddy is the least configuration for a VM; nginx gives the most control; S3 with CloudFront scales without servers.",[1111,1297,1298],{},"Atomic deploys on a VM are a release directory and a symlink swap; rollback is re-pointing the symlink.",[1111,1300,1301],{},"Put a CDN in front of a VM for global readers; edge performance then matches managed hosts.",[1111,1303,1304],{},"Choose self-hosting for control, compliance or scale economics — not to make a small site faster.",[192,1306,1308],{"id":1307},"faq","FAQ",[1310,1311,1313],"h3",{"id":1312},"why-self-host-a-static-site-when-managed-hosts-are-free","Why self-host a static site when managed hosts are free?",[14,1315,1316],{},"Common reasons are compliance or data-residency requirements, an existing cloud account and contract, predictable costs at very high traffic, integration with internal authentication, or needing full control over headers, logs and routing. For most small sites a managed static host remains simpler.",[1310,1318,1320],{"id":1319},"which-self-hosting-option-is-simplest","Which self-hosting option is simplest?",[14,1322,1323],{},"Caddy on a small VM. It serves files, obtains and renews TLS certificates automatically, compresses responses and supports clean URLs with a few lines of configuration. S3 with CloudFront scales further but needs more setup for URLs and redirects.",[1310,1325,1327],{"id":1326},"how-do-i-get-atomic-deploys-without-a-managed-host","How do I get atomic deploys without a managed host?",[14,1329,1330],{},"On a VM, upload each build to a new release directory and switch a symlink to it, which is an atomic filesystem operation. On S3, upload hashed assets first and HTML last, or deploy to a versioned prefix and switch the CloudFront origin path.",[1310,1332,1334],{"id":1333},"do-i-still-need-a-cdn-if-i-self-host-on-a-vm","Do I still need a CDN if I self-host on a VM?",[14,1336,1337],{},"For a global audience, usually yes. A single VM adds latency for distant readers and is a single point of failure. Putting a CDN in front with long cache lifetimes for hashed assets gives most of a managed host's performance.",[1310,1339,1341],{"id":1340},"what-do-managed-hosts-do-that-i-will-have-to-rebuild","What do managed hosts do that I will have to rebuild?",[14,1343,1344],{},"Atomic deploys and instant rollback, preview deploys per pull request, clean URL resolution, redirect rules, header configuration, TLS certificates and edge caching. Each is achievable when self-hosting, but each is work you now own.",[192,1346,1348],{"id":1347},"related","Related",[1108,1350,1351,1360,1365,1370,1375,1380,1385,1390,1397,1404,1411,1418,1425,1432],{},[1111,1352,1353,1356,1357,1359],{},[21,1354,1355],{},"Up:"," ",[34,1358,37],{"href":36}," — deployment options in context.",[1111,1361,1362,1364],{},[34,1363,547],{"href":546}," — the AWS setup end to end.",[1111,1366,1367,1369],{},[34,1368,672],{"href":671}," — a complete server block.",[1111,1371,1372,1374],{},[34,1373,692],{"href":691}," — automatic TLS and minimal config.",[1111,1376,1377,1379],{},[34,1378,421],{"href":420}," — making directory URLs work.",[1111,1381,1382,1384],{},[34,1383,552],{"href":551}," — redirects at the edge.",[1111,1386,1387,1389],{},[34,1388,805],{"href":804}," — atomic releases on a VM.",[1111,1391,1392,1396],{},[34,1393,1395],{"href":1394},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fatomic-deploys-vs-incremental-uploads\u002F","Atomic Deploys vs Incremental Uploads"," — why deploy atomicity matters.",[1111,1398,1399,1403],{},[34,1400,1402],{"href":1401},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fhosting-on-azure-static-web-apps\u002F","Hosting on Azure Static Web Apps"," — deploy a static site to Azure Static Web Apps.",[1111,1405,1406,1410],{},[34,1407,1409],{"href":1408},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fstatic-hosting-on-google-cloud-storage\u002F","Static Hosting on Google Cloud Storage"," — host a static site on Google Cloud Storage behind a load balancer and Cloud CDN.",[1111,1412,1413,1417],{},[34,1414,1416],{"href":1415},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fbrotli-and-gzip-precompression-served-by-nginx\u002F","Brotli and Gzip Precompression Served by Nginx"," — serve build-time Brotli and gzip files from Nginx with brotli_static and gzip_static, verify negotiation and Vary headers, and measure bytes and CPU saved.",[1111,1419,1420,1424],{},[34,1421,1423],{"href":1422},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-from-a-docker-container-with-nginx\u002F","Serving a Static Site From a Docker Container With Nginx"," — package a static site in a small Nginx container: multi-stage build, non-root user, read-only filesystem, health checks and running behind a proxy.",[1111,1426,1427,1431],{},[34,1428,1430],{"href":1429},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-caddy-and-automatic-https\u002F","Serving a Static Site With Caddy and Automatic HTTPS"," — run several static sites on one Caddy server with automatic certificates: DNS and ports, staging CA tests, rate limits, storage and wildcards.",[1111,1433,1434,1438],{},[34,1435,1437],{"href":1436},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fnginx-vs-caddy-for-serving-static-sites\u002F","Nginx vs Caddy for Serving Static Sites"," — nginx and Caddy compared serving the same static site: throughput, latency, memory, TLS automation, config size, compression and the mistakes each one invites.",[1440,1441,1442],"style",{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}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":436,"searchDepth":470,"depth":470,"links":1444},[1445,1446,1447,1448,1449,1450,1451,1452,1453,1454,1455,1456,1457,1458,1459,1460,1467],{"id":194,"depth":470,"text":195},{"id":425,"depth":470,"text":426},{"id":555,"depth":470,"text":556},{"id":675,"depth":470,"text":31},{"id":776,"depth":470,"text":777},{"id":813,"depth":470,"text":814},{"id":927,"depth":470,"text":928},{"id":959,"depth":470,"text":960},{"id":979,"depth":470,"text":980},{"id":1049,"depth":470,"text":1050},{"id":1068,"depth":470,"text":1069},{"id":1102,"depth":470,"text":1103},{"id":1145,"depth":470,"text":1146},{"id":1234,"depth":470,"text":1235},{"id":1286,"depth":470,"text":1287},{"id":1307,"depth":470,"text":1308,"children":1461},[1462,1463,1464,1465,1466],{"id":1312,"depth":485,"text":1313},{"id":1319,"depth":485,"text":1320},{"id":1326,"depth":485,"text":1327},{"id":1333,"depth":485,"text":1334},{"id":1340,"depth":485,"text":1341},{"id":1347,"depth":470,"text":1348},[1469,1472,1473],{"name":1470,"item":1471},"Home","\u002F",{"name":37,"item":36},{"name":5,"item":1474},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002F","2026-09-18","Run a static site on infrastructure you control: S3 with CloudFront, nginx or Caddy on a VM, with clean URLs, caching, redirects and zero-downtime deploys.","md",[1479,1480,1481,1482,1483],{"q":1313,"a":1316},{"q":1320,"a":1323},{"q":1327,"a":1330},{"q":1334,"a":1337},{"q":1341,"a":1344},{},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites",{"title":5,"description":1476},"self-hosting-static-sites","production-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Findex","guide","SPMmJoC4YQihIsi-cfy4O-sLxML7y_jZIyiSt_wj30w",[1492,1495,1498,1501,1504,1507,1510,1513,1516,1519,1522,1525,1528,1531,1534,1537,1540,1543,1546,1549,1552,1555,1558,1561,1564,1567,1570,1573,1576,1579,1582,1585,1588,1591,1594,1597,1600,1603,1606,1609,1612,1615,1618,1621,1624,1627,1630,1633,1636,1639,1642,1645,1648,1651,1654,1657,1660,1663,1666,1669,1672,1675,1678,1681,1684,1687,1690,1693,1696,1699,1702,1705,1708,1711,1714,1717,1720,1723,1726,1729,1732,1735,1738,1741,1744,1747,1750,1753,1756,1759,1762,1765,1768,1771,1774,1777,1780,1783,1786,1789,1792,1795,1798,1801,1804,1807,1810,1813,1816,1819,1822,1825,1828,1831,1834,1837,1840,1843,1846,1849,1852,1855,1858,1861,1864,1867,1870,1873,1876,1879,1882,1885,1888,1891,1894,1897,1900,1903,1906,1909,1912,1915,1917,1920,1923,1926,1929,1932,1935,1938,1941,1944,1947,1950,1953,1956,1959,1962,1965,1968,1971,1974,1977,1980,1983,1986,1989,1992,1995,1998,2001,2004,2007,2010,2013,2016,2019,2022,2025,2028,2031,2034,2037,2040,2043,2046,2049,2052,2055,2058,2061,2064,2067,2070,2073,2076,2079,2082,2085,2088,2091,2094,2097,2100,2103,2106,2109,2112,2115,2118,2121,2124,2127,2130,2133,2136,2139,2142,2145,2148,2151,2154,2157,2160,2163,2166,2169,2172,2175,2178,2181,2184,2187,2190,2193,2196,2199,2202,2205,2208,2211,2214,2217,2220,2223,2226,2229,2232,2235,2238,2241,2244,2247,2250,2253,2256,2259,2262,2265,2268,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,2355,2358,2361,2364,2367,2370,2372,2375,2378,2381,2384,2386,2389,2392,2395,2398,2400,2403,2406,2409,2412,2415,2418,2420,2423,2426,2429,2432,2435,2438,2440,2442,2445,2448,2451,2454,2457,2460,2463,2466,2468,2471,2474,2477,2480,2483,2486,2489,2492,2495,2498,2501,2504,2507,2510,2513,2516,2518,2521,2523,2526,2529,2532,2535,2538,2540,2542,2544,2546,2548,2549,2551,2553,2555,2557,2559,2561,2563,2566,2569,2572,2575,2578,2581,2584,2587,2590,2593,2596,2599,2602,2605,2608,2611,2614],{"path":1493,"title":1494},"\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":1496,"title":1497},"\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":1499,"title":1500},"\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":1502,"title":1503},"\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":1505,"title":1506},"\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":1508,"title":1509},"\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":1511,"title":1512},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Faccessibility-for-static-sites","Accessibility for Static Sites",{"path":1514,"title":1515},"\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":1517,"title":1518},"\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":1520,"title":1521},"\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":1523,"title":1524},"\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":1526,"title":1527},"\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":1529,"title":1530},"\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":1532,"title":1533},"\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":1535,"title":1536},"\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":1538,"title":1539},"\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":1541,"title":1542},"\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":1544,"title":1545},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fastro-vs-eleventy-for-documentation-sites","Astro vs Eleventy for Documentation Sites",{"path":1547,"title":1548},"\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":1550,"title":1551},"\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":1553,"title":1554},"\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":1556,"title":1557},"\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":1559,"title":1560},"\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":1562,"title":1563},"\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":1565,"title":1566},"\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":1568,"title":1569},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fcomparing-docs-framework-build-times","Comparing Docs Framework Build Times",{"path":1571,"title":1572},"\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":1574,"title":1575},"\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":1577,"title":1578},"\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":1580,"title":1581},"\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":1583,"title":1584},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress","Docs Frameworks: Docusaurus, Starlight and VitePress",{"path":1586,"title":1587},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Finternationalizing-starlight-docs","Internationalizing Starlight Docs",{"path":1589,"title":1590},"\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":1592,"title":1593},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fmigrating-from-mkdocs-to-starlight","Migrating from MkDocs to Starlight",{"path":1595,"title":1596},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fmigrating-mkdocs-documentation-to-vitepress","Migrating MkDocs Documentation to VitePress",{"path":1598,"title":1599},"\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":1601,"title":1602},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fversioned-documentation-with-docusaurus","Versioned Documentation with Docusaurus",{"path":1604,"title":1605},"\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":1607,"title":1608},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fdocs-frameworks-docusaurus-starlight-vitepress\u002Fvitepress-for-library-documentation","VitePress for Library Documentation",{"path":1610,"title":1611},"\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":1613,"title":1614},"\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":1616,"title":1617},"\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":1619,"title":1620},"\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":1622,"title":1623},"\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":1625,"title":1626},"\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":1628,"title":1629},"\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":1631,"title":1632},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fhugo-build-times-for-large-repositories","Hugo Build Times for Large Repositories",{"path":1634,"title":1635},"\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":1637,"title":1638},"\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":1640,"title":1641},"\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":1643,"title":1644},"\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":1646,"title":1647},"\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":1649,"title":1650},"\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":1652,"title":1653},"\u002Fchoosing-the-right-static-site-generator-for-production","Choosing the Right Static Site Generator for Production",{"path":1655,"title":1656},"\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":1658,"title":1659},"\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":1661,"title":1662},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites\u002Fi18n-routing-in-astro","i18n Routing in Astro",{"path":1664,"title":1665},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites","Internationalization for Static Sites",{"path":1667,"title":1668},"\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":1670,"title":1671},"\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":1673,"title":1674},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Finternationalization-for-static-sites\u002Fmultilingual-sites-with-hugo","Multilingual Sites with Hugo",{"path":1676,"title":1677},"\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":1679,"title":1680},"\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":1682,"title":1683},"\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":1685,"title":1686},"\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":1688,"title":1689},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fdeploying-jekyll-with-github-actions","Deploying Jekyll with GitHub Actions",{"path":1691,"title":1692},"\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":1694,"title":1695},"\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":1697,"title":1698},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem","Jekyll Plugin Ecosystem",{"path":1700,"title":1701},"\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":1703,"title":1704},"\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":1706,"title":1707},"\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":1709,"title":1710},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fspeeding-up-slow-jekyll-builds","Speeding Up Slow Jekyll Builds",{"path":1712,"title":1713},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fjekyll-plugin-ecosystem\u002Fupgrading-jekyll-and-ruby-versions-safely","Upgrading Jekyll and Ruby Versions Safely",{"path":1715,"title":1716},"\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":1718,"title":1719},"\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":1721,"title":1722},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators","Migrating Between Static Site Generators",{"path":1724,"title":1725},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fkeeping-redirects-working-after-an-ssg-migration","Keeping Redirects Working After an SSG Migration",{"path":1727,"title":1728},"\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":1730,"title":1731},"\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":1733,"title":1734},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-from-docusaurus-to-starlight","Migrating from Docusaurus to Starlight",{"path":1736,"title":1737},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fmigrating-between-static-site-generators\u002Fmigrating-from-gatsby-to-astro","Migrating from Gatsby to Astro",{"path":1739,"title":1740},"\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":1742,"title":1743},"\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":1745,"title":1746},"\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":1748,"title":1749},"\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":1751,"title":1752},"\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":1754,"title":1755},"\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":1757,"title":1758},"\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":1760,"title":1761},"\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":1763,"title":1764},"\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":1766,"title":1767},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites","Next.js Static Export for Content Sites",{"path":1769,"title":1770},"\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":1772,"title":1773},"\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":1775,"title":1776},"\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":1778,"title":1779},"\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":1781,"title":1782},"\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":1784,"title":1785},"\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":1787,"title":1788},"\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":1790,"title":1791},"\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":1793,"title":1794},"\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":1796,"title":1797},"\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":1799,"title":1800},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fcustomizing-the-pagefind-ui","Customizing the Pagefind UI",{"path":1802,"title":1803},"\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":1805,"title":1806},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites","Search for Static Sites",{"path":1808,"title":1809},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Findexing-hugo-sites-with-pagefind","Indexing Hugo Sites with Pagefind",{"path":1811,"title":1812},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fmultilingual-search-on-static-sites","Multilingual Search on Static Sites",{"path":1814,"title":1815},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Fpagefind-vs-algolia-docsearch","Pagefind vs Algolia DocSearch",{"path":1817,"title":1818},"\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":1820,"title":1821},"\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":1823,"title":1824},"\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":1826,"title":1827},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fsearch-for-static-sites\u002Ftracking-zero-result-searches","Tracking Zero-Result Searches",{"path":1829,"title":1830},"\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":1832,"title":1833},"\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":1835,"title":1836},"\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":1838,"title":1839},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix\u002Fevaluating-ssg-accessibility-defaults","Evaluating SSG Accessibility Defaults",{"path":1841,"title":1842},"\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":1844,"title":1845},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Fssg-framework-selection-matrix","SSG Framework Selection Matrix",{"path":1847,"title":1848},"\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":1850,"title":1851},"\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":1853,"title":1854},"\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":1856,"title":1857},"\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":1859,"title":1860},"\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":1862,"title":1863},"\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":1865,"title":1866},"\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":1868,"title":1869},"\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":1871,"title":1872},"\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":1874,"title":1875},"\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":1877,"title":1878},"\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":1880,"title":1881},"\u002Fchoosing-the-right-static-site-generator-for-production\u002Ftechnical-seo-for-static-sites","Technical SEO for Static Sites",{"path":1883,"title":1884},"\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":1886,"title":1887},"\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":1889,"title":1890},"\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":1892,"title":1893},"\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":1895,"title":1896},"\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":1898,"title":1899},"\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":1901,"title":1902},"\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":1904,"title":1905},"\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":1907,"title":1908},"\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":1910,"title":1911},"\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":1913,"title":1914},"\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":1916,"title":825},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs",{"path":1918,"title":1919},"\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":1921,"title":1922},"\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":1924,"title":1925},"\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":1927,"title":1928},"\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":1930,"title":1931},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Ftiered-caching-and-origin-shield","Tiered Caching and Origin Shield",{"path":1933,"title":1934},"\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":1936,"title":1937},"\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":1939,"title":1940},"\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":1942,"title":1943},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcss-and-javascript-asset-optimization","CSS and JavaScript Asset Optimization",{"path":1945,"title":1946},"\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":1948,"title":1949},"\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":1951,"title":1952},"\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":1954,"title":1955},"\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":1957,"title":1958},"\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":1960,"title":1961},"\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":1963,"title":1964},"\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":1966,"title":1967},"\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":1969,"title":1970},"\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":1972,"title":1973},"\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":1975,"title":1976},"\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":1978,"title":1979},"\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":1981,"title":1982},"\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":1984,"title":1985},"\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":1987,"title":1988},"\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":1990,"title":1991},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcumulative-layout-shift-fixes-for-static-sites","Cumulative Layout Shift Fixes for Static Sites",{"path":1993,"title":1994},"\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":1996,"title":1997},"\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":1999,"title":2000},"\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":2002,"title":2003},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fauditing-font-payload-per-page","Auditing Font Payload per Page",{"path":2005,"title":2006},"\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":2008,"title":2009},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Ffont-display-optional-vs-swap","font-display: optional vs swap",{"path":2011,"title":2012},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites","Font Loading Strategies for Static Sites",{"path":2014,"title":2015},"\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":2017,"title":2018},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fpreloading-fonts-without-double-downloads","Preloading Fonts Without Double Downloads",{"path":2020,"title":2021},"\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":2023,"title":2024},"\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":2026,"title":2027},"\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":2029,"title":2030},"\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":2032,"title":2033},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Ffont-loading-strategies-for-static-sites\u002Fvariable-fonts-vs-static-weights","Variable Fonts vs Static Weights",{"path":2035,"title":2036},"\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":2038,"title":2039},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fblur-up-placeholders-with-lqip","Blur-Up Placeholders with LQIP",{"path":2041,"title":2042},"\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":2044,"title":2045},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro\u002Fcaching-processed-images-between-builds","Caching Processed Images Between Builds",{"path":2047,"title":2048},"\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":2050,"title":2051},"\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":2053,"title":2054},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fimage-optimization-pipelines-in-astro","Image Optimization Pipelines in Astro",{"path":2056,"title":2057},"\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":2059,"title":2060},"\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":2062,"title":2063},"\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":2065,"title":2066},"\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":2068,"title":2069},"\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":2071,"title":2072},"\u002Fperformance-optimization-core-web-vitals-for-ssgs","Core Web Vitals Optimization for SSGs",{"path":2074,"title":2075},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fastro-islands-vs-full-hydration-performance","Astro Islands vs Full Hydration Performance",{"path":2077,"title":2078},"\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":2080,"title":2081},"\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":2083,"title":2084},"\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":2086,"title":2087},"\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":2089,"title":2090},"\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":2092,"title":2093},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering","JavaScript Hydration & Partial Rendering",{"path":2095,"title":2096},"\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":2098,"title":2099},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fpreact-vs-react-islands-bundle-size","Preact vs React Islands Bundle Size",{"path":2101,"title":2102},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Freplacing-react-islands-with-web-components","Replacing React Islands with Web Components",{"path":2104,"title":2105},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fjavascript-hydration-partial-rendering\u002Fserver-islands-in-astro","Server Islands in Astro",{"path":2107,"title":2108},"\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":2110,"title":2111},"\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":2113,"title":2114},"\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":2116,"title":2117},"\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":2119,"title":2120},"\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":2122,"title":2123},"\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":2125,"title":2126},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Flargest-contentful-paint-optimization-for-static-sites","Largest Contentful Paint Optimization for Static Sites",{"path":2128,"title":2129},"\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":2131,"title":2132},"\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":2134,"title":2135},"\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":2137,"title":2138},"\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":2140,"title":2141},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci","Performance Budgets and Lighthouse CI",{"path":2143,"title":2144},"\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":2146,"title":2147},"\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":2149,"title":2150},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Fper-template-performance-budgets","Per-Template Performance Budgets",{"path":2152,"title":2153},"\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":2155,"title":2156},"\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":2158,"title":2159},"\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":2161,"title":2162},"\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":2164,"title":2165},"\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":2167,"title":2168},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fperformance-budgets-and-lighthouse-ci\u002Ftracking-page-weight-over-time","Tracking Page Weight Over Time",{"path":2170,"title":2171},"\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":2173,"title":2174},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fauditing-unused-preloads","Auditing Unused Preloads",{"path":2176,"title":2177},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fearly-hints-103-on-cloudflare","Early Hints (103) on Cloudflare",{"path":2179,"title":2180},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Ffetchpriority-beyond-the-hero-image","Fetchpriority Beyond the Hero Image",{"path":2182,"title":2183},"\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":2185,"title":2186},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed","Resource Hints and Navigation Speed",{"path":2188,"title":2189},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Finstant-navigation-with-speculation-rules","Instant Navigation with Speculation Rules",{"path":2191,"title":2192},"\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":2194,"title":2195},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fresource-hints-and-navigation-speed\u002Fprefetching-links-in-astro","Prefetching Links in Astro",{"path":2197,"title":2198},"\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":2200,"title":2201},"\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":2203,"title":2204},"\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":2206,"title":2207},"\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":2209,"title":2210},"\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":2212,"title":2213},"\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fthird-party-script-performance-on-static-sites","Third-Party Script Performance on Static Sites",{"path":2215,"title":2216},"\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":2218,"title":2219},"\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":2221,"title":2222},"\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":2224,"title":2225},"\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":2227,"title":2228},"\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":2230,"title":2231},"\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":2233,"title":2234},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fautomating-eleventy-deployments-with-cloudflare-pages","Automating Eleventy Deployments on Cloudflare Pages",{"path":2236,"title":2237},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fbranch-deploy-controls-on-cloudflare-pages","Branch Deploy Controls on Cloudflare Pages",{"path":2239,"title":2240},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fcloudflare-pages-functions-middleware","Cloudflare Pages Functions Middleware",{"path":2242,"title":2243},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Fconfiguring-redirects-on-cloudflare-pages","Configuring Redirects on Cloudflare Pages",{"path":2245,"title":2246},"\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":2248,"title":2249},"\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":2251,"title":2252},"\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":2254,"title":2255},"\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":2257,"title":2258},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup\u002Ffixing-redirect-loops-on-cloudflare-pages","Fixing Redirect Loops on Cloudflare Pages",{"path":2260,"title":2261},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcloudflare-pages-edge-caching-setup","Cloudflare Pages Edge Caching Setup",{"path":2263,"title":2264},"\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":2266,"title":2267},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fchecking-links-in-pull-requests","Checking Links in Pull Requests",{"path":2269,"title":2270},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fcontent-linting-with-markdownlint","Content Linting with markdownlint",{"path":2272,"title":2273},"\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":2275,"title":2276},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Feditorial-checks-with-vale-in-ci","Editorial Checks with Vale in CI",{"path":2278,"title":2279},"\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":2281,"title":2282},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams","Content Workflows for Documentation Teams",{"path":2284,"title":2285},"\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":2287,"title":2288},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Frelease-notes-and-changelogs-from-git","Release Notes and Changelogs from Git",{"path":2290,"title":2291},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fcontent-workflows-for-documentation-teams\u002Fscheduled-content-publishing-with-github-actions","Scheduled Content Publishing With GitHub Actions",{"path":2293,"title":2294},"\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":2296,"title":2297},"\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":2299,"title":2300},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fbuilding-astro-sites-with-github-actions","Building Astro Sites with GitHub Actions",{"path":2302,"title":2303},"\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":2305,"title":2306},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fconcurrency-groups-to-cancel-stale-builds","Concurrency Groups to Cancel Stale Builds",{"path":2308,"title":2309},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fdeploying-to-github-pages-with-actions","Deploying to GitHub Pages with Actions",{"path":2311,"title":2312},"\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":2314,"title":2315},"\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":2317,"title":2318},"\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":2320,"title":2321},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds","GitHub Actions for Automated SSG Builds",{"path":2323,"title":2324},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fmatrix-builds-for-multi-site-monorepos","Matrix Builds for Multi-Site Monorepos",{"path":2326,"title":2327},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Fpinning-actions-by-commit-sha","Pinning Actions by Commit SHA",{"path":2329,"title":2330},"\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":2332,"title":2333},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fgithub-actions-for-automated-ssg-builds\u002Freusable-workflows-for-ssg-builds","Reusable Workflows for SSG Builds",{"path":2335,"title":2336},"\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":2338,"title":2339},"\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":2341,"title":2342},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fdeploying-only-changed-files","Deploying Only Changed Files",{"path":2344,"title":2345},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fenabling-incremental-builds-in-eleventy","Enabling Incremental Builds in Eleventy",{"path":2347,"title":2348},"\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":2350,"title":2351},"\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":2353,"title":2354},"\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":2356,"title":2357},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs","Incremental Builds and Build Caching for SSGs",{"path":2359,"title":2360},"\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":2362,"title":2363},"\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":2365,"title":2366},"\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":2368,"title":2369},"\u002Fproduction-ready-deployment-cicd-workflows","Production-Ready Deployment & CI\u002FCD for SSGs",{"path":2371,"title":1064},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Falerting-on-cache-hit-ratio-drops",{"path":2373,"title":2374},"\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":2376,"title":2377},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fcrawling-for-broken-links-on-a-schedule","Crawling for Broken Links on a Schedule",{"path":2379,"title":2380},"\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":2382,"title":2383},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production","Monitoring Static Sites in Production",{"path":2385,"title":1060},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Flogging-404s-at-the-edge",{"path":2387,"title":2388},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fmonitoring-tls-certificate-expiry","Monitoring TLS Certificate Expiry",{"path":2390,"title":2391},"\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":2393,"title":2394},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fsynthetic-monitoring-with-scheduled-playwright-checks","Synthetic Monitoring With Scheduled Playwright Checks",{"path":2396,"title":2397},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Ftracking-deploy-markers-in-analytics","Tracking Deploy Markers in Analytics",{"path":2399,"title":1132},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fmonitoring-static-sites-in-production\u002Fuptime-and-synthetic-checks-for-static-sites",{"path":2401,"title":2402},"\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":2404,"title":2405},"\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":2407,"title":2408},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fconfiguring-vercel-for-hugo-and-eleventy","Configuring Vercel for Hugo and Eleventy",{"path":2410,"title":2411},"\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":2413,"title":2414},"\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":2416,"title":2417},"\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":2419,"title":42},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies",{"path":2421,"title":2422},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-build-hooks-for-content-updates","Netlify Build Hooks for Content Updates",{"path":2424,"title":2425},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-edge-functions-for-static-sites","Netlify Edge Functions for Static Sites",{"path":2427,"title":2428},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fnetlify-vs-vercel-deployment-strategies\u002Fnetlify-redirects-and-rewrites-for-static-sites","Netlify Redirects and Rewrites for Static Sites",{"path":2430,"title":2431},"\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":2433,"title":2434},"\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":2436,"title":2437},"\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":2439,"title":1088},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fautomating-preview-deploy-pipelines-with-github-actions",{"path":2441,"title":1099},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fcleaning-up-stale-preview-deployments",{"path":2443,"title":2444},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fcommenting-on-preview-deploys","Commenting on Preview Deploys",{"path":2446,"title":2447},"\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":2449,"title":2450},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests","Preview Environments for Pull Requests",{"path":2452,"title":2453},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpassword-protecting-preview-deployments","Password-Protecting Preview Deployments",{"path":2455,"title":2456},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpreview-deploys-for-monorepos","Preview Deploys for Monorepos",{"path":2458,"title":2459},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fpreviewing-headless-cms-drafts","Previewing Headless CMS Drafts",{"path":2461,"title":2462},"\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":2464,"title":2465},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fpreview-environments-for-pull-requests\u002Fvisual-regression-testing-on-preview-deploys","Visual Regression Testing on Preview Deploys",{"path":2467,"title":1395},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fatomic-deploys-vs-incremental-uploads",{"path":2469,"title":2470},"\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":2472,"title":2473},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fcanary-releases-for-static-sites","Canary Releases for Static Sites",{"path":2475,"title":2476},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Ffeature-flags-on-static-sites","Feature Flags on Static Sites",{"path":2478,"title":2479},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites","Rollbacks and Deploy Safety for Static Sites",{"path":2481,"title":2482},"\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":2484,"title":2485},"\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fpost-deploy-verification-checklists","Post-Deploy Verification Checklists",{"path":2487,"title":2488},"\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":2490,"title":2491},"\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":2493,"title":2494},"\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":2496,"title":2497},"\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":2499,"title":2500},"\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":2502,"title":2503},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fauditing-npm-dependencies-in-ssg-pipelines","Auditing npm Dependencies in SSG Pipelines",{"path":2505,"title":2506},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fenabling-hsts-and-preload-safely","Enabling HSTS and Preload Safely",{"path":2508,"title":2509},"\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":2511,"title":2512},"\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":2514,"title":2515},"\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":2517,"title":967},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites",{"path":2519,"title":2520},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fpermissions-policy-and-cross-origin-headers","Permissions-Policy and Cross-Origin Headers",{"path":2522,"title":1142},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsecuring-deploy-credentials-with-github-oidc",{"path":2524,"title":2525},"\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":2527,"title":2528},"\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":2530,"title":2531},"\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":2533,"title":2534},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsubresource-integrity-for-third-party-assets","Subresource Integrity for Third-Party Assets",{"path":2536,"title":2537},"\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":2539,"title":1416},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fbrotli-and-gzip-precompression-served-by-nginx",{"path":2541,"title":421},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fclean-urls-and-trailing-slashes-on-s3",{"path":2543,"title":552},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fcloudfront-functions-for-redirects",{"path":2545,"title":547},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fdeploying-a-static-site-to-s3-and-cloudfront",{"path":2547,"title":1402},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fhosting-on-azure-static-web-apps",{"path":1485,"title":5},{"path":2550,"title":1437},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fnginx-vs-caddy-for-serving-static-sites",{"path":2552,"title":1423},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-from-a-docker-container-with-nginx",{"path":2554,"title":1430},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-caddy-and-automatic-https",{"path":2556,"title":692},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-caddy",{"path":2558,"title":672},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fserving-a-static-site-with-nginx",{"path":2560,"title":1409},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fstatic-hosting-on-google-cloud-storage",{"path":2562,"title":805},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fzero-downtime-deploys-with-symlink-swaps",{"path":2564,"title":2565},"\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":2567,"title":2568},"\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":2570,"title":2571},"\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":2573,"title":2574},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites","Serverless Functions for Static Sites",{"path":2576,"title":2577},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fnetlify-functions-vs-cloudflare-workers","Netlify Functions vs Cloudflare Workers",{"path":2579,"title":2580},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fnewsletter-signup-with-an-edge-function","Newsletter Signup with an Edge Function",{"path":2582,"title":2583},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Fprotecting-a-static-site-behind-authentication","Protecting a Static Site Behind Authentication",{"path":2585,"title":2586},"\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":2588,"title":2589},"\u002Fproduction-ready-deployment-cicd-workflows\u002Fserverless-functions-for-static-sites\u002Frate-limiting-edge-functions","Rate Limiting Edge Functions",{"path":2591,"title":2592},"\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":2594,"title":2595},"\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":2597,"title":2598},"\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":2600,"title":2601},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci","Testing Static Sites in CI",{"path":2603,"title":2604},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Fsnapshot-testing-build-output","Snapshot Testing Build Output",{"path":2606,"title":2607},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Ftesting-redirects-and-headers-before-deploy","Testing Redirects and Headers Before Deploy",{"path":2609,"title":2610},"\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":2612,"title":2613},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Ftesting-structured-data-and-meta-tags","Testing Structured Data and Meta Tags",{"path":2615,"title":2616},"\u002Fproduction-ready-deployment-cicd-workflows\u002Ftesting-static-sites-in-ci\u002Fvalidating-html-output-in-ci","Validating HTML Output in CI",null,1790943190979]