Add a Simple Frontend to View Uploaded Files
Build a small HTML frontend that calls the metadata list API and configure CORS for your API Gateway.
All services used in this lesson are covered by the AWS Free Tier.
AWS Services Used
Learning Outcomes
By the end of this lesson, you will be able to:
- Build a small HTML frontend that calls the metadata list API.
- Explain why CORS is required when a site hosted on one origin calls an API hosted on another origin.
- Configure CORS for an API Gateway HTTP API.
- Deploy the frontend to an S3 static website bucket.
- Render a list of uploaded files returned by the API.
The Core Idea
You already built the backend pieces: S3 for uploads, Lambda for processing, DynamoDB for metadata, and API Gateway for read and list endpoints.
Now you will add a tiny browser frontend that calls GET /metadata/list and shows the results on a page.
Why CORS Matters Here
CORS (Cross-Origin Resource Sharing) is required when a web app hosted on one domain (origin) calls an API hosted on another. In this lesson:
- Your frontend origin is your S3 website endpoint.
- Your API origin is your API Gateway execute-api URL.
Because these origins are different, you must configure your HTTP API to explicitly allow requests from your frontend origin.
Part 1: Enable CORS on the HTTP API
Open your API Gateway HTTP API and configure CORS. A safe starting setup is:
- Allow origin: your S3 website URL (e.g.,
http://bucket-name.s3-website-region.amazonaws.com) - Allow methods:
GET - Allow headers:
Content-Type
Part 2: Create the Frontend File
Create a file named index.html with this content:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Uploaded Files Viewer</title>
<style>
body { font-family: sans-serif; max-width: 760px; margin: 40px auto; padding: 0 16px; line-height: 1.5; }
form { display: grid; gap: 12px; margin: 20px 0; }
input, button { padding: 10px 12px; font-size: 16px; }
.card { border: 5px solid #ddd; border-radius: 10px; padding: 12px; margin-top: 12px; }
.muted { color: #666; font-size: 14px; }
.error { color: #b00020; margin-top: 12px; }
</style>
</head>
<body>
<h1>Uploaded Files Viewer</h1>
<form id="searchForm">
<input id="bucket" type="text" placeholder="Bucket name" required />
<input id="prefix" type="text" placeholder="Prefix (optional), e.g. incoming/" />
<button type="submit">Load files</button>
</form>
<div id="status" class="muted"></div>
<div id="error" class="error"></div>
<div id="results"></div>
<script>
const API_BASE_URL = "YOUR_API_BASE_URL";
const form = document.getElementById("searchForm");
form.addEventListener("submit", async (event) => {
event.preventDefault();
const bucket = document.getElementById("bucket").value.trim();
const prefix = document.getElementById("prefix").value.trim();
const params = new URLSearchParams({ bucket });
if (prefix) params.set("prefix", prefix);
try {
const response = await fetch(`${API_BASE_URL}/metadata/list?${params.toString()}`);
const data = await response.json();
if (!response.ok) throw new Error(data.error || "Request failed");
document.getElementById("results").innerHTML = data.items.map(item => `
<div class="card">
<strong>${item.object_key}</strong>
<div class="muted">Size: ${item.size} bytes | Event: ${item.event_name}</div>
</div>
`).join("");
} catch (error) {
document.getElementById("error").textContent = error.message;
}
});
</script>
</body>
</html>
Part 3: Add your Real API URL
Replace YOUR_API_BASE_URL in the script with your actual API Gateway base URL (e.g., https://abc123.execute-api.us-east-1.amazonaws.com).
Part 4: Upload the Frontend to S3
- Upload
index.htmlto your S3 website bucket. - Ensure Static website hosting is enabled on the bucket.
- Open the Website endpoint provided by S3.
Part 5: Test the Flow
- Open your frontend in the browser.
- Enter your upload bucket name.
- Enter the prefix
incoming/. - Submit and verify that your file metadata appears.
Lab Checklist
| Step | Success Condition |
|---|---|
| Enable CORS on HTTP API | Browser is allowed to call the API |
| Create index.html | Frontend file exists |
| Add real API base URL | Frontend points to your API |
| Upload to S3 bucket | Frontend is hosted |
| Submit bucket/prefix | API request runs and returns metadata |
Micro-activity 1: Reflection
Think about it
After the lab, reflect: What website URL did you open? What API base URL did you configure? What bucket did you search? Did the page render files or an error?
Micro-activity 2: Match Each Service's Role
Match each service to what it does in this lesson
Examples
Choose one, then match it on the right
Characteristics
Select an example first
0 of 4 matched so far.
Summary
In this lesson, you added the user-facing piece: a static frontend that calls your API and renders metadata. You learned that CORS is essential when your frontend and backend live on different origins.