- Newest
- Most votes
- Most comments
You're right that this is a common setup for Single Page Applications (SPAs) with an API backend, and it can be frustrating to implement. However, there are ways to achieve your requirements using CloudFront and its associated services. Here's how you can address your two requirements:
-
For API routes returning errors: You can use CloudFront's origin groups feature to set up separate error handling for your API origin. Create an origin group that includes your ALB origin, and configure it to pass through all status codes. This way, any errors from your API will be returned as-is.
-
For SPA routes returning errors: To serve index.html with a 200 status code for all non-API routes that result in errors, you can use a combination of CloudFront's custom error responses and Lambda@Edge.
First, set up a custom error response in CloudFront for your S3 origin. Configure it to respond with your index.html file for 4xx errors.
Then, use a Lambda@Edge function associated with the Origin Response event. This function will run after S3 responds but before CloudFront sends the response to the viewer. In this function, you can check if the response is an error (status code >= 400) and if it's not an API route. If both conditions are true, modify the response to have a 200 status code.
Here's a basic outline of the Lambda@Edge function:
exports.handler = async (event) => { const response = event.Records[0].cf.response; const request = event.Records[0].cf.request; if (response.status >= 400 && !request.uri.startsWith('/api/')) { response.status = 200; response.statusDescription = 'OK'; } return response; };
While setting up Lambda@Edge might seem complex for a simple task, it provides the flexibility you need to handle this scenario correctly. It allows you to maintain the correct behavior for both your API and SPA routes.
Remember to configure your S3 bucket for website hosting and set the index document to index.html. This ensures that requests for directory paths (like /about/) will serve the index.html file.
By combining these approaches, you can achieve your requirements: API errors will be passed through as-is, while other routes will serve index.html with a 200 status code in case of errors, allowing your SPA to handle routing on the client side.
Sources
Deploy a React-based single-page application to Amazon S3 and CloudFront - AWS Prescriptive Guidance
Requests can't be served when sending requests to cloudfront alternate domain name | AWS re:Post
How to Solve: 403 Forbidden Error in Cloudfront (API Gateway)? | AWS re:Post
Hello ,
I understand your requirement but optimal solution is using Lambda@Edge Origin response function. This should be configured for your default behavior where the origin is S3, as this is the most effective way to achieve your desired architecture.
While alternatives like custom error pages and CloudFront functions exist, they won't provide the ability to handle redirections for a specific behavior. For instance, custom error pages would affect all behaviors globally rather than allowing specific handling for one behavior.
Your architecture with CloudFront will look like this :
Client - - - - - - > CloudFront - - - - > behaviour [1] Default - - - -> Origin S3, behaviour [2] API - - - - > Origin API
Configuration Overview:
-
Default Behavior (S3 Origin):
- Implement Lambda@Edge with Origin Response trigger
- Handle response codes >= 400 with redirect to index.html
- Return 200 OK status code
-
API Behavior (/api/*):
- Maintain original error handling
- Error codes will be passed through to the client
Please refer the below documentation related to the redirection using status code you can use the snippets provided below to modify it according to your use case : [+] https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-examples.html#lambda-examples-update-error-status-examples
Relevant content
- asked 12 days ago
- AWS OFFICIALUpdated 6 months ago