DEV Community

paulmojicatech
paulmojicatech

Posted on • Edited on

NGINX and Angular SPA Redirect

Purpose

In this post, we will discuss how to configure NGINX when hosting an Angular application so that refreshing a page does not give you a 404 error.

The Problem

SPA's (Single Page Applications) have changed the way we develop web applications in the last 8 - 10 years (though it is falling out of fashion lately per my post). A SPA runs the entire application on the client (browser). This makes an application much more responsive.

However, one of the pitfalls is that routing also happens on the client. This becomes an issue both with SEO (search engine optimization) as well as trying to refresh a route that is not the home route. The problem is that the web server does not know the route because routing happens on the client. So foo.com/bar is an unknown route to the web server. The web server only know foo.com and it serves the index.html page when that requests comes in. The /bar piece is something that the client knows how to handle because there is javascript sent from the web server to the client that is knows how the routing should work.

The Solution

There are several solutions to get around the routing issue. One is to use MPA's (multi page applications). Both Angular (Angular Universal, Scully, and more recently released Analog) and React (NextJs and Remix) have meta-frameworks that provide a server side rendered solution.

The other solution, which is the one this article will discuss, is allowing NGINX handle the routing.

NGINX Config

NGINX is a very fast reverse proxy that acts as a web server to host your web app. It has several configuration files that decide how incoming requests to the web server should be handled.

Below is a snippet of the configuration you can add that will serve the index.html file (which contains the SPA routing information) to all unknown incoming URLs.

server {
      listen 80;
      listen [::]:80;
      server_name localhost;

      location / {
            root /usr/share/nginx/html;
            index index.html;
            try_files $uri $uri/ /index.html =404;
      }
}
Enter fullscreen mode Exit fullscreen mode

The important part of this code block is try_files $uri $uri/ /index.html =404;. This tells NGINX if a URL comes in that it does not recognize, use the URI (Uniform Resource Identifier) and serve the index.html file. Note: The =404; part should never be hit but it is common practice to add it as well. This says if index.html is not found, serve the default 404 page.

Conclusion

This was a short article the shows how you can configure NGINX to workaround a limitation in SPAs where routing is broken because the web server does not know how to process routes be default.

If you would like to hear more about web development, please follow me on BlueSky, Mastodon(@paulmojicatech@hachyderm.io), or LinkedIn.

Happy Coding!

Top comments (2)

Collapse
 
jakdev003 profile image
Josh K • Edited

I am trying to serve multiple apps in one file. With the config below I can get to the default route for each app but I cannot go to any other routes in the app.

What am I doing wrong?

Here is my nginx.config

server {   

    listen 80; 
    listen [::]:80;

    location /apps/ui-showcase { 
        root /usr/share/nginx/html; 
        index  index.html; 
        try_files $uri $uri/ /index.html =404; 
    }

    location /apps/system-settings { 
        root /usr/share/nginx/html; 
        index  index.html; 
        try_files $uri $uri/ /index.html =404; 
    } 

    location /apps/login{ 
        root /usr/share/nginx/html; 
        index  index.html; 
        try_files $uri $uri/ /index.html /index.html?args =404; 
    } 

    location /apps/administration { 
        root /usr/share/nginx/html; 
        index  index.html; 
        try_files $uri $uri/ /index.html =404; 
    } 
} 
Enter fullscreen mode Exit fullscreen mode
Collapse
 
gokul_202f071e0c643bf0f54 profile image
Gokul

Hey Josh!!

I hope you are doing great. Can you please let me know if you resolved this ?
I too stucking here.