Vue.js Project on AWS S3 (with CloudFront)
This guide explains how to host your Vue.js site using Amazon S3 for storage and Amazon CloudFront as a Content Delivery Network (CDN). This architecture provides a highly scalable and cost-effective solution for serving static applications globally.
Prerequisites
Before you begin, ensure you have a working Vue.js project and an AWS account. You also need the AWS CLI installed on your local machine to handle deployments. If you have not already initialized your project, follow this guide first.
Step 1: Configure the S3 Bucket
Amazon S3 acts as the origin for your static files. Navigate to the S3 Dashboard and create a new bucket using a unique name. While many developers name the bucket after their domain for organization, it is not a technical requirement when using CloudFront. Select your preferred region, such as ap-south-2 (Hyderabad).
Keep the Block all public access setting enabled. This is the recommended security practice when using CloudFront. You will use an Origin Access Control (OAC) to allow CloudFront to fetch files securely without making the bucket public to the entire internet.
Step 2: Manage SSL Certificates
To serve your application over HTTPS with a custom domain, you must request an SSL certificate. Amazon CloudFront requires these certificates to be created in the us-east-1 (N. Virginia) region, regardless of where your S3 bucket is located.
Navigate to the Certificate Manager (ACM) in the North Virginia region and select Request a certificate. Add your fully qualified domain names and choose DNS Validation. After you submit the request, AWS provides a unique CNAME name and a CNAME value that you must add to your domain's DNS records to prove ownership.
If your domain is managed through AWS Route 53, you can use the automated button to create these records. If you use any other DNS provider, copy the CNAME details from the AWS console and manually add them as a new record in your provider's dashboard. The certificate status will change to Issued once the DNS changes propagate, which usually takes about 30 minutes.
Step 3: Create the CloudFront Distribution
CloudFront speeds up the delivery of your site by caching content at edge locations closer to your users.
Navigate to the CloudFront Distributions Console and create a new distribution using the following options:
- Plan: Free (recommended) or "Pay as you go"
- Distribution Name: Your Distribution Name
- Distribution Type: Single website or app
- Route 53 managed domain: leave blank
- Origin Type: Amazon S3
- S3 Origin: your-bucket-name.s3.ap-south-2.amazonaws.com
- Origin Path: leave blank
- Allow private S3 bucket access to CloudFront: Enable
- This should automatically add a Bucket Policy to allow CloudFront distribution.
- Origin settings: Use recommended origin settings
- CloudFront automatically creates an Origin Access Control (OAC) with signed requests.
- Cache settings: Customize cache settings
- Viewer protocol policy:
Redirect HTTP to HTTPS - Allowed HTTP methods:
GET, HEAD, OPTIONS(No cache for OPTIONS) - Cache policy: CachingOptimized
- Origin request policy: leave blank
- Response headers policy:
CORS-with-preflight-and-SecurityHeadersPolicy - Web Application Firewall (WAF):
included in Free plan
- Viewer protocol policy:
- Default root object:
index.html
Handle Single Page Application (SPA) Routing
Since Vue.js is a Single Page Application, you must configure CloudFront to handle client-side routing. Without this, refreshing the browser on a sub-page (like /dashboard) will result in a 404 error from S3.
Open your CloudFront distribution and navigate to the Error responses tab. Click Create custom error response and add the following settings for both 403: Forbidden and 404: Not Found errors.
- HTTP error code: 404 (and 403)
- Customize error response: Yes
- Response page path:
/index.html - HTTP Response Code:
200: OK
Custom Domain
To use a custom subdomain (such as app.example.com), do this:
- Navigate to the CloudFront Distributions Console and click "Add domain" under "General" tab of your CloudFront distribution.
- TLS Certificate: Select the SSL certificate you created in Step 2 from the dropdown menu.
Step 4: Point Your Domain to CloudFront
The final connection is to tell your domain registrar to send traffic to CloudFront. Copy the Distribution domain name (which looks like d123.cloudfront.net) from the CloudFront General tab.
If you use Route 53, create an A record and toggle the Alias switch to point to your distribution. For other providers, create a CNAME record with your subdomain as the name and the CloudFront address as the value. Your site will be live once the DNS changes finish spreading across the internet.
Step 5: Local Deployment Setup
To deploy changes from your local machine, you must configure the AWS CLI with your credentials. Open your terminal and run the configuration command:
aws configure
# Enter your Access Key, Secret Key, and default region (e.g., ap-south-2)Deployment Alias
You can create a deployment alias in your ~/.bashrc or ~/.zshrc file to automate the build and sync process. This command builds your Vue.js project, syncs the local distribution folder with S3, and clears the CloudFront cache so your changes appear instantly.
# Replace <your-bucket-name> and <your-distribution-id>
alias deploy_vue="npm run build && aws s3 sync dist/ s3://<your-bucket-name> --delete && aws cloudfront create-invalidation --distribution-id <your-distribution-id> --paths '/*'"# Replace <your-bucket-name> and <your-distribution-id>
alias deploy_vue="yarn build && aws s3 sync dist/ s3://<your-bucket-name> --delete && aws cloudfront create-invalidation --distribution-id <your-distribution-id> --paths '/*'"# Replace <your-bucket-name> and <your-distribution-id>
alias deploy_vue="pnpm build && aws s3 sync dist/ s3://<your-bucket-name> --delete && aws cloudfront create-invalidation --distribution-id <your-distribution-id> --paths '/*'"# Replace <your-bucket-name> and <your-distribution-id>
alias deploy_vue="bun run build && aws s3 sync dist/ s3://<your-bucket-name> --delete && aws cloudfront create-invalidation --distribution-id <your-distribution-id> --paths '/*'"The --delete flag ensures that files removed from your local project are also removed from S3 to keep your bucket clean.
You should now have a production-ready Vue.js site running on AWS infrastructure with global acceleration and a secure SSL certificate.
