Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 10 + AWS S3 + Cloudfront: navigation without a hash

I've seen many questions here that address this but using an apache server, for my application, I'm using AWS S3 with Cloudfront, I need the application to work without the ugly hash on the URL.

Is there any approach that can be done to be able to refresh, or hit links directly without using the hash?

If any part of the code is required I can include it but I don't see the need for it since nothing is failing, I just need a working strategy.

Regards.

My app routing module

@NgModule({
  imports: [
    RouterModule.forRoot(routes, { useHash: true })
  ],
  exports: [
    RouterModule
  ]
})

Removing the hash true works for navigation but not for page refresh or direct links

like image 302
Danny22 Avatar asked Oct 17 '25 11:10

Danny22


1 Answers

Before writing the solution, let me shortly explain what is needed to be done. In general, page navigation in single page applications (SPA) is achieved by javascript code manipulating the view and/or monitoring the url and navigation history events. When you launch the app and click different links, for example /user, application is not reloaded, it is still the same app loaded via root index.html which reacts to the clicked link by changing to the corresponding view or component and modifying the url in the address bar.

However, if you navigate to the example.com/user directly after opening browser (without initial load of the root example.com), browser will send request to the /user path which doesn't actually exist nor in S3 bucket, neither in cloudfront distribution, though it will be failed. Our aim is to force S3 and Cloudfront to always return the root index.html file, independently of what was the original path of the request.

In order to achieve that you need slightly change the configuration of S3 bucket and Cloudfront distribution.

Before moving to the AWS related changes, change the useHash property of the RouterModule import to false:

RouterModule.forRoot(routes, { useHash: false })
  1. Open your S3 bucket in the AWS web console, go to the "properties" tab, find the "static website hosting" section, enable it if it was disabled and put index.html into both fields: index document and error document.

enter image description here

Then save the configuration. Actually now your index.html file will be served for any path same as for the root one. You should already notice that when you open your website after above changes applied. However, you will notice that the response code is 404 despite application opens correctly - it happens because it is still the "not found" response as the path doesn't exist. There are some changes needed in the cloudfront configuration too to make this working even better.

  1. Navigate to the cloudfront distribution page in aws web console. I assume that since you already have cloudfront distribution (you mentioned it in the question) then you probably have all the default setups already and your S3 bucket is already connected as an origin for this distribution. Navigate to the "error pages" tab and press "create new custom error response". Click "yes" in the "customize" input, select error code 404, write "/index.html" in the "response page path" input and select code 200OK for the response. Then save the configuration. It may take a few minutes to start working.

enter image description here

Now try to open the website - you should not see 404 responses anymore because now all the requests (even to not existing paths) have code 200.

like image 99
Artem Arkhipov Avatar answered Oct 20 '25 02:10

Artem Arkhipov



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!