[{"data":1,"prerenderedAt":121},["ShallowReactive",2],{"hub:tools-aws":3},{"path":4,"key":5,"title":6,"h1":7,"description":8,"crumbs":9,"blocks":17},"\u002Ftools\u002Faws\u002F","tools-aws","Static Sites on AWS: S3 and CloudFront","AWS (S3 and CloudFront)","Guides for hosting static sites on S3 and CloudFront: clean URLs, CloudFront Functions, cache keys, Origin Shield and blue-green deploys.",[10,13,16],[11,12],"Home","\u002F",[14,15],"Tools","\u002Ftools\u002F",[7,4],[18,21,24,33,35,59,98,100],{"k":19,"text":20},"p","S3 behind CloudFront is the most common way to host a static site inside an organisation’s own cloud account, and it is where the conveniences of managed static hosts have to be rebuilt by hand: clean URLs and trailing slashes, redirects, atomic deploys, previews and rollbacks. The guides below rebuild each of them, and cover the CloudFront settings — cache policies, error caching, Origin Shield — that decide how often requests reach the bucket at all.",{"k":22,"html":23},"fig","\u003Cfigure>\n\u003Csvg viewBox=\"0 0 760 383\" role=\"img\" aria-labelledby=\"hub-aws-hero-title hub-aws-hero-desc\" xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\">\n  \u003Ctitle id=\"hub-aws-hero-title\">Request path through CloudFront and S3\u003C\u002Ftitle>\n  \u003Cdesc id=\"hub-aws-hero-desc\">Four layers. A CloudFront Function handles redirects and clean URLs at the viewer request. The CloudFront cache policy decides the cache key and TTLs. Origin Shield collapses misses into one regional request. The S3 bucket, private behind origin access control, holds the files.\u003C\u002Fdesc>\n  \u003Crect x=\"0\" y=\"0\" width=\"760\" height=\"383\" fill=\"#ffffff\"\u002F>\n  \u003Cg style=\"font-family:system-ui, sans-serif;font-size:12px\">\n    \u003Crect x=\"40.0\" y=\"60.0\" width=\"440.0\" height=\"57.2\" rx=\"8\" fill=\"#6a4c93\" opacity=\"0.14\" stroke=\"#6a4c93\" style=\"stroke-width:1.5px\"\u002F>\n    \u003Cpath d=\"M260.0 119.2 L260.0 139.2\" fill=\"none\" stroke=\"#556071\" style=\"stroke-width:2px;marker-end:url(#hub-aws-hero-arrow)\"\u002F>\n    \u003Crect x=\"40.0\" y=\"143.2\" width=\"440.0\" height=\"57.2\" rx=\"8\" fill=\"#1982c4\" opacity=\"0.14\" stroke=\"#1982c4\" style=\"stroke-width:1.5px\"\u002F>\n    \u003Cpath d=\"M260.0 202.4 L260.0 222.4\" fill=\"none\" stroke=\"#556071\" style=\"stroke-width:2px;marker-end:url(#hub-aws-hero-arrow)\"\u002F>\n    \u003Crect x=\"40.0\" y=\"226.4\" width=\"440.0\" height=\"57.2\" rx=\"8\" fill=\"#ffca3a\" opacity=\"0.24\" stroke=\"#a97b00\" style=\"stroke-width:1.5px\"\u002F>\n    \u003Cpath d=\"M260.0 285.6 L260.0 305.6\" fill=\"none\" stroke=\"#556071\" style=\"stroke-width:2px;marker-end:url(#hub-aws-hero-arrow)\"\u002F>\n    \u003Crect x=\"40.0\" y=\"309.6\" width=\"440.0\" height=\"57.2\" rx=\"8\" fill=\"#8ac926\" opacity=\"0.2\" stroke=\"#5a8a16\" style=\"stroke-width:1.5px\"\u002F>\n    \u003Ctext x=\"380.0\" y=\"30.0\" fill=\"#1f2937\" style=\"font-size:16px;text-anchor:middle;font-weight:700\">A static site on AWS, layer by layer\u003C\u002Ftext>\n    \u003Ctext x=\"260.0\" y=\"86.4\" fill=\"#1f2937\" style=\"font-size:13px;text-anchor:middle;font-weight:700\">CloudFront Function\u003C\u002Ftext>\n    \u003Ctext x=\"260.0\" y=\"103.3\" fill=\"#556071\" style=\"font-size:11px;text-anchor:middle\">redirects, clean URLs\u003C\u002Ftext>\n    \u003Ctext x=\"504.0\" y=\"92.6\" fill=\"#556071\" style=\"font-size:11.5px;text-anchor:start\">viewer request\u003C\u002Ftext>\n    \u003Ctext x=\"260.0\" y=\"169.5\" fill=\"#1f2937\" style=\"font-size:13px;text-anchor:middle;font-weight:700\">Cache policy\u003C\u002Ftext>\n    \u003Ctext x=\"260.0\" y=\"186.4\" fill=\"#556071\" style=\"font-size:11px;text-anchor:middle\">keys, TTLs, error caching\u003C\u002Ftext>\n    \u003Ctext x=\"504.0\" y=\"175.8\" fill=\"#556071\" style=\"font-size:11.5px;text-anchor:start\">hit ratio lives here\u003C\u002Ftext>\n    \u003Ctext x=\"260.0\" y=\"252.7\" fill=\"#1f2937\" style=\"font-size:13px;text-anchor:middle;font-weight:700\">Origin Shield\u003C\u002Ftext>\n    \u003Ctext x=\"260.0\" y=\"269.6\" fill=\"#556071\" style=\"font-size:11px;text-anchor:middle\">regional tier\u003C\u002Ftext>\n    \u003Ctext x=\"504.0\" y=\"259.0\" fill=\"#556071\" style=\"font-size:11.5px;text-anchor:start\">fewer origin requests\u003C\u002Ftext>\n    \u003Ctext x=\"260.0\" y=\"335.9\" fill=\"#1f2937\" style=\"font-size:13px;text-anchor:middle;font-weight:700\">S3 bucket\u003C\u002Ftext>\n    \u003Ctext x=\"260.0\" y=\"352.8\" fill=\"#556071\" style=\"font-size:11px;text-anchor:middle\">private, origin access control\u003C\u002Ftext>\n    \u003Ctext x=\"504.0\" y=\"342.2\" fill=\"#556071\" style=\"font-size:11.5px;text-anchor:start\">the files\u003C\u002Ftext>\n  \u003C\u002Fg>\n  \u003Cdefs>\n    \u003Cmarker id=\"hub-aws-hero-arrow\" viewBox=\"0 0 10 10\" refX=\"8\" refY=\"5\" markerWidth=\"7\" markerHeight=\"7\" orient=\"auto-start-reverse\">\n      \u003Cpath d=\"M0 0 L10 5 L0 10 z\" fill=\"#556071\"\u002F>\n    \u003C\u002Fmarker>\n  \u003C\u002Fdefs>\n\u003C\u002Fsvg>\n\u003Cfigcaption>Every layer has at least one guide below; most problems come from the top two.\u003C\u002Ffigcaption>\n\u003C\u002Ffigure>",{"k":25,"h":26,"items":27},"group","Choosing the Right Static Site Generator for Production",[28],{"t":29,"u":30,"d":31,"y":32},"Trailing Slash and basePath in Next.js Static Export","\u002Fchoosing-the-right-static-site-generator-for-production\u002Fnextjs-static-export-for-content-sites\u002Ftrailing-slash-and-basepath-in-nextjs-static-export\u002F","Configure trailingSlash, basePath and assetPrefix in a Next.js static export so links, assets, canonicals and host URL handling agree on every static host.","How-to",{"k":22,"html":34},"\u003Cfigure>\n\u003Csvg viewBox=\"0 0 760 295\" role=\"img\" aria-labelledby=\"hub-aws-kinds-title hub-aws-kinds-desc\" xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\">\n  \u003Ctitle id=\"hub-aws-kinds-title\">Number of AWS (S3 and CloudFront) guides of each kind\u003C\u002Ftitle>\n  \u003Cdesc id=\"hub-aws-kinds-desc\">Vertical bars: How-tos 13, Fixes 0, Comparisons 2 and Concepts 0.\u003C\u002Fdesc>\n  \u003Crect x=\"0\" y=\"0\" width=\"760\" height=\"295\" fill=\"#ffffff\"\u002F>\n  \u003Cg style=\"font-family:system-ui, sans-serif;font-size:12px\">\n    \u003Crect x=\"80.0\" y=\"76.0\" width=\"90.0\" height=\"170.0\" rx=\"3\" fill=\"#1982c4\" opacity=\"0.3\" stroke=\"#1982c4\" style=\"stroke-width:1px\"\u002F>\n    \u003Crect x=\"250.0\" y=\"243.0\" width=\"90.0\" height=\"3.0\" rx=\"3\" fill=\"#ff595e\" opacity=\"0.3\" stroke=\"#d83b41\" style=\"stroke-width:1px\"\u002F>\n    \u003Crect x=\"420.0\" y=\"219.8\" width=\"90.0\" height=\"26.2\" rx=\"3\" fill=\"#ffca3a\" opacity=\"0.45\" stroke=\"#a97b00\" style=\"stroke-width:1px\"\u002F>\n    \u003Crect x=\"590.0\" y=\"243.0\" width=\"90.0\" height=\"3.0\" rx=\"3\" fill=\"#6a4c93\" opacity=\"0.3\" stroke=\"#6a4c93\" style=\"stroke-width:1px\"\u002F>\n    \u003Cpath d=\"M30.0 246.0 L730.0 246.0\" fill=\"none\" stroke=\"#556071\" style=\"stroke-width:1.5px\"\u002F>\n    \u003Ctext x=\"380.0\" y=\"30.0\" fill=\"#1f2937\" style=\"font-size:16px;text-anchor:middle;font-weight:700\">AWS (S3 and CloudFront) guides by kind\u003C\u002Ftext>\n    \u003Ctext x=\"125.0\" y=\"69.0\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:middle;font-weight:700\">13\u003C\u002Ftext>\n    \u003Ctext x=\"125.0\" y=\"264.0\" fill=\"#556071\" style=\"font-size:11.5px;text-anchor:middle\">How-tos\u003C\u002Ftext>\n    \u003Ctext x=\"295.0\" y=\"236.0\" fill=\"#b32b30\" style=\"font-size:12px;text-anchor:middle;font-weight:700\">0\u003C\u002Ftext>\n    \u003Ctext x=\"295.0\" y=\"264.0\" fill=\"#556071\" style=\"font-size:11.5px;text-anchor:middle\">Fixes\u003C\u002Ftext>\n    \u003Ctext x=\"465.0\" y=\"212.8\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:middle;font-weight:700\">2\u003C\u002Ftext>\n    \u003Ctext x=\"465.0\" y=\"264.0\" fill=\"#556071\" style=\"font-size:11.5px;text-anchor:middle\">Comparisons\u003C\u002Ftext>\n    \u003Ctext x=\"635.0\" y=\"236.0\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:middle;font-weight:700\">0\u003C\u002Ftext>\n    \u003Ctext x=\"635.0\" y=\"264.0\" fill=\"#556071\" style=\"font-size:11.5px;text-anchor:middle\">Concepts\u003C\u002Ftext>\n  \u003C\u002Fg>\n\u003C\u002Fsvg>\n\u003Cfigcaption>15 guides use AWS (S3 and CloudFront) in depth; each is listed below under the section it belongs to.\u003C\u002Ffigcaption>\n\u003C\u002Ffigure>",{"k":25,"h":36,"items":37},"Core Web Vitals Optimization for SSGs",[38,43,47,51,55],{"t":39,"u":40,"d":41,"y":42},"Cloudflare vs CloudFront Cache Hit Ratios for Static Sites","\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fcloudflare-vs-cloudfront-cache-hit-ratios-for-static-sites\u002F","Cloudflare and CloudFront measured serving the same static site: cache hit ratio, origin requests, TTFB by region and cost, plus the settings that moved each.","Comparison",{"t":44,"u":45,"d":46,"y":32},"Cache Keys and Query Strings on CDNs","\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fcache-keys-and-query-strings-on-cdns\u002F","Stop tracking parameters from fragmenting a static site’s CDN cache: normalize query strings in the cache key on Cloudflare and CloudFront, and measure hit ratio.",{"t":48,"u":49,"d":50,"y":32},"Cache-Control Headers on S3 and CloudFront","\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fcache-control-headers-on-s3-and-cloudfront\u002F","Set Cache-Control for a static site on S3 behind CloudFront: object metadata on upload, cache policies, response headers policies and invalidation, measured.",{"t":52,"u":53,"d":54,"y":32},"Caching 404s and Redirects at the Edge","\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Fcaching-404s-and-redirects-at-the-edge\u002F","Cache 404 pages and redirects on a static site’s CDN so bots, broken links and migration redirects stop hitting the origin, without making fixes slow to appear.",{"t":56,"u":57,"d":58,"y":32},"Tiered Caching and Origin Shield","\u002Fperformance-optimization-core-web-vitals-for-ssgs\u002Fcdn-caching-rules-for-ssgs\u002Ftiered-caching-and-origin-shield\u002F","Use Cloudflare Tiered Cache or CloudFront Origin Shield so edge misses on a static site are served from a regional tier instead of the origin, with measured results.",{"k":25,"h":60,"items":61},"Production-Ready Deployment & CI\u002FCD for SSGs",[62,66,70,74,78,82,86,90,94],{"t":63,"u":64,"d":65,"y":42},"Atomic Deploys vs Incremental Uploads","\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fatomic-deploys-vs-incremental-uploads\u002F","Why syncing files into a live bucket serves broken pages, how atomic publishing works, and how to build atomicity yourself on S3, object storage or a VM origin.",{"t":67,"u":68,"d":69,"y":32},"Blue-Green Deploys for Static Sites","\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Fblue-green-deploys-for-static-sites\u002F","Run blue-green deploys for a self-hosted static site: two complete environments, verification before switching, an instant switch at the CDN and one-step rollback.",{"t":71,"u":72,"d":73,"y":32},"Clean URLs and Trailing Slashes on S3","\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fclean-urls-and-trailing-slashes-on-s3\u002F","Make directory-style URLs work on S3 behind CloudFront: a viewer-request function for index files, one canonical trailing-slash form, and tests that prove it.",{"t":75,"u":76,"d":77,"y":32},"CloudFront Functions for Redirects","\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fcloudfront-functions-for-redirects\u002F","Serve hundreds of redirects for a static site on S3 from a CloudFront Function and KeyValueStore, generated from the build and tested on every deploy.",{"t":79,"u":80,"d":81,"y":32},"Deploying Only Changed Files","\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fdeploying-only-changed-files\u002F","Upload only the files that changed in a static site deploy using content hashes, rsync or S3 sync with checksums, while keeping the deploy atomic and purges scoped.",{"t":83,"u":84,"d":85,"y":32},"Deploying a Static Site to S3 and CloudFront","\u002Fproduction-ready-deployment-cicd-workflows\u002Fself-hosting-static-sites\u002Fdeploying-a-static-site-to-s3-and-cloudfront\u002F","Deploy a static site to a private S3 bucket behind CloudFront with Origin Access Control, split cache headers, ordered uploads and a targeted invalidation.",{"t":87,"u":88,"d":89,"y":32},"Rolling Back S3 and CloudFront Deploys With Versioned Prefixes","\u002Fproduction-ready-deployment-cicd-workflows\u002Frollbacks-and-deploy-safety-for-static-sites\u002Frolling-back-s3-and-cloudfront-deploys-with-versioned-prefixes\u002F","Make S3 and CloudFront deploys atomic by uploading each build to its own prefix and switching CloudFront's origin path, so a rollback takes one config change.",{"t":91,"u":92,"d":93,"y":32},"Securing Deploy Credentials with GitHub OIDC","\u002Fproduction-ready-deployment-cicd-workflows\u002Fsecurity-headers-for-static-sites\u002Fsecuring-deploy-credentials-with-github-oidc\u002F","Replace long-lived deploy tokens with short-lived OIDC credentials in GitHub Actions for AWS, Cloudflare and Netlify, scoped to one branch and one deploy job.",{"t":95,"u":96,"d":97,"y":32},"Sharing Build Cache Across CI Runners","\u002Fproduction-ready-deployment-cicd-workflows\u002Fincremental-builds-and-build-caching-for-ssgs\u002Fsharing-build-cache-across-ci-runners\u002F","Share a build cache across parallel CI runners with Turborepo remote cache, an S3-backed store, or scoped actions\u002Fcache. Architecture, signing, and measured savings.",{"k":22,"html":99},"\u003Cfigure>\n\u003Csvg viewBox=\"0 0 760 278\" role=\"img\" aria-labelledby=\"hub-aws-topics-title hub-aws-topics-desc\" xmlns=\"http:\u002F\u002Fwww.w3.org\u002F2000\u002Fsvg\">\n  \u003Ctitle id=\"hub-aws-topics-title\">Topics with the most AWS (S3 and CloudFront) guides\u003C\u002Ftitle>\n  \u003Cdesc id=\"hub-aws-topics-desc\">Horizontal bars, largest first: CDN Caching Rules for SSGs 5, Rollbacks and Deploy Safety for Static Sites 3, Self-Hosting Static Sites on S3, Nginx and Caddy 3, Incremental Builds and Build Caching for SSGs 2, Next.js Static Export for Content Sites 1 and Security Headers and Hardening for Static Sites 1.\u003C\u002Fdesc>\n  \u003Crect x=\"0\" y=\"0\" width=\"760\" height=\"278\" fill=\"#ffffff\"\u002F>\n  \u003Cg style=\"font-family:system-ui, sans-serif;font-size:12px\">\n    \u003Crect x=\"350.0\" y=\"65.0\" width=\"365.6\" height=\"20.0\" rx=\"3\" fill=\"#6a4c93\" opacity=\"0.3\" stroke=\"#6a4c93\" style=\"stroke-width:1px\"\u002F>\n    \u003Crect x=\"350.0\" y=\"99.0\" width=\"219.4\" height=\"20.0\" rx=\"3\" fill=\"#6a4c93\" opacity=\"0.3\" stroke=\"#6a4c93\" style=\"stroke-width:1px\"\u002F>\n    \u003Crect x=\"350.0\" y=\"133.0\" width=\"219.4\" height=\"20.0\" rx=\"3\" fill=\"#6a4c93\" opacity=\"0.3\" stroke=\"#6a4c93\" style=\"stroke-width:1px\"\u002F>\n    \u003Crect x=\"350.0\" y=\"167.0\" width=\"146.2\" height=\"20.0\" rx=\"3\" fill=\"#6a4c93\" opacity=\"0.3\" stroke=\"#6a4c93\" style=\"stroke-width:1px\"\u002F>\n    \u003Crect x=\"350.0\" y=\"201.0\" width=\"73.1\" height=\"20.0\" rx=\"3\" fill=\"#6a4c93\" opacity=\"0.3\" stroke=\"#6a4c93\" style=\"stroke-width:1px\"\u002F>\n    \u003Crect x=\"350.0\" y=\"235.0\" width=\"73.1\" height=\"20.0\" rx=\"3\" fill=\"#6a4c93\" opacity=\"0.3\" stroke=\"#6a4c93\" style=\"stroke-width:1px\"\u002F>\n    \u003Cpath d=\"M350.0 60.0 L350.0 260.0\" fill=\"none\" stroke=\"#556071\" style=\"stroke-width:1.5px\"\u002F>\n    \u003Ctext x=\"380.0\" y=\"30.0\" fill=\"#1f2937\" style=\"font-size:16px;text-anchor:middle;font-weight:700\">Where AWS (S3 and CloudFront) comes up\u003C\u002Ftext>\n    \u003Ctext x=\"20.0\" y=\"79.2\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:start\">CDN Caching Rules\u003C\u002Ftext>\n    \u003Ctext x=\"723.6\" y=\"79.5\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:start;font-weight:700\">5\u003C\u002Ftext>\n    \u003Ctext x=\"20.0\" y=\"113.2\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:start\">Rollbacks and Deploy Safety\u003C\u002Ftext>\n    \u003Ctext x=\"577.4\" y=\"113.5\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:start;font-weight:700\">3\u003C\u002Ftext>\n    \u003Ctext x=\"20.0\" y=\"147.2\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:start\">Self-Hosting Static Sites on S3, Nginx…\u003C\u002Ftext>\n    \u003Ctext x=\"577.4\" y=\"147.5\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:start;font-weight:700\">3\u003C\u002Ftext>\n    \u003Ctext x=\"20.0\" y=\"181.2\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:start\">Incremental Builds and Build Caching\u003C\u002Ftext>\n    \u003Ctext x=\"504.2\" y=\"181.5\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:start;font-weight:700\">2\u003C\u002Ftext>\n    \u003Ctext x=\"20.0\" y=\"215.2\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:start\">Next.js Static Export for Content Sites\u003C\u002Ftext>\n    \u003Ctext x=\"431.1\" y=\"215.5\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:start;font-weight:700\">1\u003C\u002Ftext>\n    \u003Ctext x=\"20.0\" y=\"249.2\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:start\">Security Headers and Hardening\u003C\u002Ftext>\n    \u003Ctext x=\"431.1\" y=\"249.5\" fill=\"#1f2937\" style=\"font-size:12px;text-anchor:start;font-weight:700\">1\u003C\u002Ftext>\n  \u003C\u002Fg>\n\u003C\u002Fsvg>\n\u003Cfigcaption>Topic pages give the wider context for each group; the numbers count only guides that use this tool in depth.\u003C\u002Ffigcaption>\n\u003C\u002Ffigure>",{"k":25,"h":101,"items":102},"Often used with AWS (S3 and CloudFront)",[103,108,113,117],{"t":104,"u":105,"d":106,"y":107},"Cloudflare","\u002Ftools\u002Fcloudflare\u002F","Pages and Workers hosting, cache rules and edge functions.","4 shared guides",{"t":109,"u":110,"d":111,"y":112},"Next.js","\u002Ftools\u002Fnextjs\u002F","Static export for content sites, its limits and alternatives.","1 shared guides",{"t":114,"u":115,"d":116,"y":112},"Netlify","\u002Ftools\u002Fnetlify\u002F","Headers, redirects, deploy previews and build caching.",{"t":118,"u":119,"d":120,"y":112},"GitHub Actions","\u002Ftools\u002Fgithub-actions\u002F","Caching, matrix builds, reusable workflows and pinning.",1790943190468]