In this post, I’ll guide you through the steps to host a Vue.js Single Page Application (SPA) on AWS using S3 and CloudFront. This setup is perfect for ensuring that your Vue.js app functions efficiently, with all internal routing handled properly.
Step 1: Create a Private S3 Bucket
Start by creating a private S3 bucket to store your Vue.js app files. It's essential to keep the bucket private, as we’ll be using CloudFront to serve content securely.
Here’s how you create the S3 bucket:
After creating the bucket, make sure its permissions are set to private.
Now that your S3 bucket is created, it’s time to upload your Vue.js app bundle.
Step 2: Upload Your Vue.js Application Bundle
Once you’ve built your Vue.js app, upload the bundled files (such as JavaScript, CSS, and HTML files) into the S3 bucket. After uploading, your bucket contents might look like this:
Step 3: Enable Static Website Hosting
Next, enable Static Website Hosting for your S3 bucket. Set both the Index Document and Error Document to index.html
. This ensures that all routing will be handled by the index.html
page, and your Vue.js application can manage the internal routing.
Here’s what the static website hosting setup should look like:
Step 4: Create a CloudFront Distribution
Now it’s time to set up CloudFront to serve your app. Go to CloudFront and create a new distribution. When setting the origin, choose the S3 bucket you just created. For enhanced security, select Origin Access Control (OAC), which limits direct access to the bucket and serves files only through CloudFront.
Here’s what the CloudFront origin settings look like:
During the setup, you’ll need to create an OAC policy that allows CloudFront to access your S3 bucket securely:
Once the CloudFront distribution is created, update your bucket’s permissions by editing the Bucket Policy. This ensures that CloudFront can access your S3 bucket contents. Here’s a sample policy that allows CloudFront to fetch your files:
{
"Version": "2008-10-17",
"Id": "PolicyForCloudFrontPrivateContent",
"Statement": [
{
"Sid": "AllowCloudFrontServicePrincipal",
"Effect": "Allow",
"Principal": {
"Service": "cloudfront.amazonaws.com"
},
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::<your-bucket-name>/*",
"Condition": {
"StringEquals": {
"AWS:SourceArn": "arn:aws:cloudfront::<your-aws-account-id>:distribution/<your-cloudfront-distribution-id>"
}
}
}
]
}
You can get the policy directly from AWS after creating the distribution or use the above template, replacing the placeholders with your details. To apply it, go to the Bucket Policy section under the Permissions tab in S3.
Step 5: Configure CloudFront Distribution Settings
After your CloudFront distribution is created, configure it to point to index.html
as the default root object. This ensures that your root URL always loads the Vue.js entry point.
Here’s how the settings should look:
Step 6: Create a Custom Error Response for 403 Errors
Vue.js SPAs rely on internal routing for navigation. When you refresh a page or try to access a direct route, CloudFront may not find the requested file and will return a 403 error. To avoid this, create a custom error response in CloudFront.
Under the Error Pages tab, add a new custom error response for 403 errors, pointing the Response Page Path to index.html
and setting the HTTP response code to 200
. This will ensure that CloudFront serves the index.html
file for any undefined route, letting Vue.js handle the internal routing. Described more about the error here.
Here’s how to configure the custom error response:
Once set up, your CloudFront custom error response should look like this:
Conclusion
By following these steps, you can successfully deploy your Vue.js Single Page Application using AWS S3 and CloudFront. With this setup, all your routes will work correctly, even on refresh, thanks to the proper configuration of the static website hosting, CloudFront distribution, and custom error responses.
Top comments (0)