AWS S3
Static Website Hosting
Directory Listing
Cloud Storage
S3 Bucket

Directory Listing in S3 Static Website

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

S3 static website hosting does not provide an automatic Apache-style directory listing. If a user browses to a prefix, S3 will not generate an index of objects for you. To get directory-style browsing, you need to build that behavior yourself, either by generating index pages ahead of time or by serving object listings through another layer.

Why S3 Does Not List Directories Natively

S3 is object storage, not a hierarchical web server. The path-looking structure is really key prefixes inside a flat bucket namespace.

That means two things:

  • folders are a naming convention, not real directories
  • the static website endpoint serves objects, not generated listings

If there is no index.html for a given prefix, you do not get a directory listing page for free.

Option 1: Pre-Generate Index Pages

The simplest approach is to generate an index.html file for each prefix you want to browse. That works well when the bucket contents change infrequently.

Example with Python and boto3:

python
1import boto3
2
3s3 = boto3.client("s3")
4bucket = "my-static-site"
5prefix = "docs/"
6
7response = s3.list_objects_v2(Bucket=bucket, Prefix=prefix, Delimiter="/")
8
9items = []
10for obj in response.get("Contents", []):
11    key = obj["Key"]
12    if key != prefix:
13        items.append(f'<li><a href="/{key}">{key}</a></li>')
14
15html = "<html><body><ul>" + "".join(items) + "</ul></body></html>"
16
17s3.put_object(
18    Bucket=bucket,
19    Key=f"{prefix}index.html",
20    Body=html.encode("utf-8"),
21    ContentType="text/html",
22)

This does not make S3 dynamic. It simply creates the file S3 needs in order to serve a listing-like page.

Option 2: Put a Dynamic Layer in Front

If bucket contents change frequently, a generated static index may go stale too often. In that case, a dynamic layer is more appropriate:

  • Lambda behind API Gateway
  • CloudFront plus Lambda or CloudFront Functions
  • a small application that lists S3 objects and renders HTML or JSON

This gives you real-time listings, but it is no longer "just S3 static website hosting." You are adding compute and routing logic.

That tradeoff is often worth it if the bucket behaves more like a file browser than like a classic static website.

Security and Access Design Matter

Directory listing can expose more than intended if you simply dump every object key into a public page. Before building it, decide:

  • which prefixes are public
  • whether filenames reveal sensitive information
  • whether listing should be filtered or paginated

S3 object access and S3 listing are related but not identical concerns. A bucket can contain objects you do not want discoverable through a browsable index.

Use the Right Model for the Use Case

If your goal is a polished public website, pre-generated pages are often enough. If your goal is a browsable file repository, S3 static website hosting may not be the best standalone tool. A lightweight app or a dedicated file-browser layer may fit better.

This is the core architectural point: directory listing is not missing because you overlooked one checkbox. It is absent because S3's website feature is intentionally simple.

Common Pitfalls

  • Expecting S3 static website hosting to generate directory listings automatically.
  • Forgetting that S3 prefixes are not true filesystem directories.
  • Making every object key publicly discoverable without thinking about information exposure.
  • Using a static generated index for rapidly changing bucket contents and then wondering why listings are stale.
  • Treating directory listing as an S3 setting instead of as an application behavior you must implement.

Summary

  • S3 static website hosting does not natively support automatic directory listing.
  • The usual workaround is to generate index.html files for each browsable prefix.
  • For dynamic listings, add a compute layer such as Lambda or an application backend.
  • Design listing behavior with access control and information exposure in mind.
  • If directory browsing is central to the product, consider whether plain S3 static hosting is the right foundation.

Course illustration
Course illustration

All Rights Reserved.