๐ชฃ Hosting a Static Website on AWS S3
Not every website needs a server. If your site is just HTML, CSS, and JavaScript โ no backend, no database โ Amazon S3 can host it directly, cheaply, and reliably. No EC2 instance, no server management, no patching.
In this post, we'll take a simple 3-file website (index.html, error.html, script.js) and host it on S3 as a public static website.
๐ง Why S3 for Static Hosting?
- No servers to manage or patch
- Extremely low cost (pay only for storage + requests)
- Scales automatically โ handles a handful of visitors or a viral spike the same way
- Great for portfolios, landing pages, documentation sites, or single-page apps
๐ผ๏ธ Architecture
Flow:
Browser Request โ S3 Bucket (Static Website Hosting enabled)
โ
โโโ index.html (default page)
โโโ error.html (shown on 404 / errors)
โโโ script.js (site logic)
โ Prerequisites
- An AWS account
- Three simple files ready to upload:
-
index.htmlโ your homepage -
error.htmlโ shown when a page/object isn't found -
script.jsโ any JavaScript your site uses
-
Example minimal files, if you don't have your own yet:
index.html
<!DOCTYPE html>
<html>
<head>
<title>My S3 Website</title>
<script src="script.js"></script>
</head>
<body>
<h1>Hello from my S3 Static Website!</h1>
</body>
</html>
error.html
<!DOCTYPE html>
<html>
<head>
<title>Page Not Found</title>
</head>
<body>
<h1>Oops! That page doesn't exist.</h1>
</body>
</html>
script.js
console.log("Site loaded successfully from S3!");
Step 1: Create the S3 Bucket
- Go to S3 Console โ Create Bucket
-
Bucket name: must be globally unique, e.g.
my-static-site-demo-2026 -
Region: choose your preferred region (e.g.,
ap-south-1) - Block Public Access settings: Uncheck "Block all public access" โ a static website needs to be publicly readable > โ ๏ธ Acknowledge the warning checkbox that appears. This is expected and required for public static hosting.
- Leave other settings as default โ Create Bucket
Step 2: Upload Your Website Files
- Open your new bucket โ Upload
- Add your three files:
index.html,error.html,style.css_script.js - Click Upload
Step 3: Enable Static Website Hosting
- In your bucket, go to Properties tab
- Scroll to Static website hosting โ Edit
- Settings:
- Static website hosting: Enable
- Hosting type: Host a static website
-
Index document:
index.html -
Error document:
error.html
- Save changes
AWS will now show you a Bucket website endpoint URL (something like http://my-static-site-demo-2026.s3-website.ap-south-1.amazonaws.com) โ keep this handy, you'll need it in Step 5.
Step 4: Add a Bucket Policy for Public Read Access
Even with "Block Public Access" disabled, S3 objects aren't public until a policy explicitly allows it.
- Go to Permissions tab โ Bucket Policy โ Edit
- Paste the following (replace
YOUR-BUCKET-NAMEwith your actual bucket name):
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "PublicReadGetObject",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::YOUR-BUCKET-NAME/*"
}
]
}
- Save changes
This policy allows anyone to read (GET) objects in the bucket โ exactly what's needed for a public website, and nothing more (no write/delete access).
Step 5: Test Your Website
Open the Bucket website endpoint URL from Step 3 in your browser:
http://YOUR-BUCKET-NAME.s3-website.<region>.amazonaws.com
You should see your index.html page render, and if you open the browser console, you should see the message from script.js logged.
Try visiting a non-existent path (e.g., add /random-page to the URL) โ you should see your custom error.html page instead of a generic AWS error.
๐ Quick Recap
| Step | What Happened |
|---|---|
| Created bucket | Storage container for website files |
| Uploaded files |
index.html, error.html, script.js
|
| Enabled static hosting | Told S3 which file is the homepage & error page |
| Added bucket policy | Made objects publicly readable |
| Tested endpoint | Confirmed the site loads and errors are handled |
๐ A Note on Security
Public bucket policies only grant read access (s3:GetObject) โ visitors can view your site, but can't upload, modify, or delete anything. Still, double check:
- Only the specific files/paths needed are public
- Sensitive files are never placed in a publicly hosted bucket
- Consider adding CloudFront in front of the bucket for HTTPS support (S3 static website endpoints don't support HTTPS natively) โ a good topic for a follow-up post!
๐งน Cleanup
To avoid any storage charges:
- Empty the bucket (Bucket โ Empty)
- Delete the bucket (Bucket โ Delete)
๐ Wrap-Up
You've now hosted a fully working static website on S3 โ no servers, no scaling concerns, just fast and cheap. This same pattern powers countless portfolios, docs sites, and landing pages in production today.
Full project files are available on GitHub.



Top comments (0)