Routing Potholes Be Gone: CloudFront to the RescueCloudFront with virtual routes — Jason Michael Perry

I recently ran into an issue when building a single page application hosted in an S3 bucket. While the app and component-based routing worked fine through clicking links, directly accessing specific path URLs would throw 404 errors.

After some digging without progress, huge thanks to my brilliant colleague Jon Hawk on the cloud team for the fix. He explained that with static SPA assets hosted on S3, the virtual component paths don’t actually exist as unique files to route requests to.

The solution is adding a CloudFront distribution in front of the S3 origin, which you need anyway for SSL certificates. CloudFront can then handle requests with a function that redirects all paths to load the index.html entry point. From there the SPA JavaScript handles rendering the matched route component.

So in summary – for SPAs on S3, use CloudFront with a handler to route all requests to index.html. Hats off to Jon for figuring that out quickly and saving my day! Let me know if others run into this redirect conundrum and I’m happy to explain more.

function handler(event) {
  var request = event.request;
  var uri = request.uri;

  // Check whether the URI is missing a file name.
  if (uri.endsWith("/")) {
    request.uri = "/index.html";
  // Check whether the URI is missing a file extension.
  else if (!uri.includes(".")) {
    request.uri = "/index.html";

  return request;