Angular Router Configuration - Apache Http Server, Nginx, Tomcat

Angular Router Configuration - Apache Http Server, Nginx, Tomcat

learninjava
May 18, 2020 - Angular
 

Concept 

So, you are here after browsing through half of the internet searching about configuring angular router or SPA in general for your production and could not get the actual idea on why its not working or what's the concept ?
Well! You are in the right place, sit tight, this is not just another Angular router configuration tutorial. We will explain what you dont find over the internet: The actual concepts of routing along with production ready configuration on three most famous servers: Apache HTTP Server, Nginx and Tomcat.
 

Client Side Vs Server Side Routing 

Why two routings required ? Why is this confusion ? Why cant we have only one ? Since SPA is client side application, why not only Client side routing works ? So many questions asked. Enough!!, Here are the answers,
See the below image, it shows how the routing works in Server side and Client side. As you can see, in a multi page application, a java web application for instance, the server refers to a configuration file. This configuration file could be a simple web.xml or if you are using a framework like Spring, it could be a applicationContext.xml file. No matter what framework you use or what configuration file you use, all it has is the routing information.
https://github.com/learninjavagithub/assets/raw/master/articles/angular-route.jpg
When a user clicks on a link to navigate to another page, the routing information is looked up in the configuration file. Then server returns the target page and the user sees the new html page. Since server is taking care of the routing its called Server side routing.
Now compare this to the single page application. In this case, there is only a single page, index.html. The webserver always returns index.html for any routing. This is because all the code is in a single page. This is why all the SPA frameworks has their own routing frameworks. In angular, its the @angular/router framework.
Such a client side routing works fine in development environment. But how can you make sure it works on a production server ? Since the production servers are created before SPA frameworks came in to usage, we need special instructions for them to work with newer frameworks. That means we need a combination of Server Side and Client Side Routings.
This is why when you directly push your code to production, you will see 404 Not Found error when you refresh. This is because when you refresh on a page with URL "/user", the server tries to find that route which will not be there in server configuration The basic gist of all this conversation is this very concept of combination of Server Side Routing and Client Side Routing. When you try to route to a page say "/user", the server tries to find that page. We need to fool the server by always directing it to index.html. Once we are inside index.html, our client side routing in SPA will take care of the rest.
See below for the production ready configurations that does exactly what is explained above.
 Remember!
  • You will need both Server Side and Client Side Routing for an SPA
  • You will see 404 Not Found errors if Server Side Routing is missing or misconfigured
  • Server should be configured to always serve index.html irrespective of route
  • We have configured angular router on Angular CLI scaffolding application using @angular/cli. Let us see how to make it run on all three servers. Dont worry we have included the working application at the end. Check "Download Source" section.
    We are configuring server side configuration here, If you want to setup client side routing painlessly, head over to this easy to understand step by step tutorial - Angular Router Configuration - Angular CLI App - Step by Step
     

    HashLocationStrategy Vs PathLocationStrategy 

    There is enough information on what are the differences between HashLocationStrategy and PathLocationStrategy so we are not going to see the differences. However, we want you to understand which is used when and how they work. Think of HashLocationStrategy as a development environment routing. Although it can work on production, it appends a # in the URL which would not feel like production URLs.
    HashLocationStrategy uses browser history library and anchor blocks, also called as html bookmarks. This is the reason you dont need any server side configuration to make it working. But hold on, are you ok to have your URLs appended with an ugly #. Imagine you also have html bookmarks or anchor blocks in your pages. Then the URLs looks more uglier.
    This is where the PathLocationStrategy comes in. This is the default location strategy in Angular. Although it requires server side routing to be setup for them to work properly. This is why we used PathLocationStrategy, to make your routing production ready.
    For your reference this is how our URLs would look like if HashLocationStrategy is used:
    http://localhost:8080/angular-routing/#/dashboard
    http://localhost:8080/angular-routing/#/user
    Not so pretty right !! Read on..
     Remember!
  • HashLocationStrategy requires no Server Side Routing but appends # characters to the URLs which does not look pretty on a production environment.
  • PathLocationStrategy requires Server Side Routing which is where everyone struggles to setup. But not any more, after you read through this tutorial
  •  

    Apache HTTP Server - 2.4.43 

    1. httpd.conf - default context location (/htdocs) :

     Remember!
  • First we need to enable LoadModule rewrite_module modules/mod_rewrite.so module for the configurations to work
  • loading...

    2. httpd.conf - custom context location (say, /angular-routing) :

    This one is a bit tricky one, we need to give more information to the server to server your pages. Also, we need to create a Virtual Host and add configuration using <Directory> tag. Here are the steps:
    a. The httpd.conf configuration
    loading...

    3. .htaccess file

    loading...
    The -f, -d and -l flags represents file, directory and a symbolic link respectively. The configuration says that when you receive a request from index.html do nothing as its already in index.html, next follows the non index.html requests like "/user". In this case, we check if the request is not a file, directory or symbolic link, if so just direct them to index.html.
    Now, navigate to the dashboard screen and user screen and make sure you are not getting 404 errors when you refresh.
    https://github.com/learninjavagithub/assets/raw/master/articles/angular-route-dashboard.jpg
    https://github.com/learninjavagithub/assets/raw/master/articles/angular-route-user.jpg
     

    Nginx - 1.16.1 

    1. nginx.conf - default context location (/html) :

    This configuration is pretty simple. All we have to do is add try_files
    loading...

    2. nginx.conf - custom context location (say, /angular-routing) :

    a. The nginx.conf configuration
    loading...
     

    Tomcat - 10.0.0 

    Tomcat configuration is a bit different than other two servers. Since Tomcat only serves a web application, we need to modify our application structure to look like the structure of a Java Web Application.

    Using <error-page> in web.xml :

    Create WEB-INF folder and create a web.xml file as below and proceed with the configurations. The idea is to redirect always to index.html when 404 error occurs.
    loading...

    Using rewrite.config and Valve :

    If for some reason you dont want to use error-page, there is another approach using rewrite.config file. It uses a tomcat feature called Valve. First remove the error-page tag from web.xml and Simply create a file as below and name it as rewrite.config. Place this file in WEB-INF folder.
    loading...
    In the tomcat server.xml, add the below config and proceed with the configurations.
    loading...

    1. Default context location (/ROOT) :

    This configuration is pretty simple. All we have to do is copy the application to the ROOT folder.

    2. Custom context location (say, /angular-routing) :

    All you have to do is deploy the application to angular-routing directory in webapps
    Thats all folks !! Happy coding. If you feel this helped you, keep supporting us by   or  or  below or on the articles on social media.
     
    Like us on: