How to Deploy a React App to an AWS S3 Bucket
Introduction
If you’ve read my previous posts on AWS S3, you already know that S3 is great for file storage. But here is a cool tip: since frontend projects (like React, Angular, or Vue) build into static files, we can host them on S3 and use them just like a regular website!
In this post, I’ll show you how to deploy a React app to S3 for direct access, as well as how to set it up using CloudFront.
Prerequisites
Before we start, you should have a basic understanding of AWS S3, how to set up the AWS CDK, and how to create a Bucket.
Implementation
First, let's create a simple React project using Vite with two pages: Home and About. Feel free to use your own content!
App.tsx
Home.tsx
About.tsx
After coding, run the build command to generate the dist folder. We will use this folder for the CDK deployment.
1. Deploying the React App directly to AWS S3
Create a file named bin/react-app-s3-stack.ts with the following content:
What’s happening here?
- bucketName: Needs to be globally unique across all of AWS.
- publicReadAccess: Allows people to view your website files publicly.
- websiteIndex/ErrorDocument: We set both to index.html. This ensures that if a user refreshes the page on a React route, the app still loads correctly.
- blockPublicAccess: We modified this to allow direct S3 link access. However, this isn't the most secure method, which is why we’ll look at the CloudFront solution next.
2. Deploying to AWS S3 with CloudFront
For better security and performance, we should use CloudFront. Create bin/react-app-s3-cloudfront-stack.ts:
Key Points:
- blockPublicAccess: Now set to BLOCK_ALL. Only CloudFront can talk to S3 internally, making it much more secure.
- errorResponses: This handles "Page Not Found" errors by redirecting them to index.html, allowing React Router to take over.
- priceClass: Helps manage costs based on location:
- PRICE_CLASS_100: North America and Europe only (Cheapest).
- PRICE_CLASS_200: Includes Asia and Australia.
- PRICE_CLASS_ALL: Everywhere (Most expensive).
- Why two deployment steps?
- Step 1 (Assets): We upload everything with a long cache (365 days). Since Vite uses file hashing (e.g., main.123hash.js), these files can be safely cached forever.
- Step 2 (index.html): We override index.html with no-cache settings. This ensures users always get the latest version of your app. Note that prune: false is vital so we don't delete the assets from Step 1.
Update your bin/aws-cdk.ts file to include both stacks:
After a successful deployment, you will see the corresponding S3 and CloudFront URLs in the output.
The direct S3 link uses HTTP and not secure.
The CloudFront link supports HTTPS. While CloudFront provides a random domain name, you can always link it to your own custom domain later.
Your files are now efficiently cached and securely served!
See you again in the next article!
Comments
Post a Comment