ReactJS with NGINX: How to run an SPA alongside other proxied locations on NGINX?

Issue

I have successfully deployed a MERN stack website to a Ubuntu 20.x server using pm2 and nginx. The issue I’m facing is that URL links manually entered, or links redirected from my Express routes don’t work. This is because I have my nginx config file set up like this:

        location / {
                root /root/amfmfx.com/build;
                index index.html;
                # First attempt to serve request as file, then
                # as directory, then fall back to displaying a 
                # 404.
                try_files $uri $uri/ =404;
        }

        location /user {
                proxy_pass http://loadbalancer;
                proxy_buffering         on;
        }

        location /api {
                proxy_pass http://loadbalancer;
                proxy_buffering         on;
        }

        location /email {
                proxy_pass http://loadbalancer;
                proxy_buffering         on;
        }

The /usr, /api, and /email locations are my backend route receivers. I have Routes and Links set up in React that work perfectly when clicked on, but if I type in ‘http://mywebsite.com/login’ it comes back with an nginx error, because it’s trying to send /login to the backend apparently.

How can I configure my nginx web server to allow for manual link entries to be read by the front end, while still sending route requests to my Express server?

Thanks!

Solution

As you have the root and index in your root location any non-matching location will not have a default webroot. I would change the configuration for your react app to


server {
        // listen, server_name and friends ...

        root /root/amfmfx.com/build;
        index index.html;

        location / {
          try_files $uri $uri/ /index.html;
        }

        location /user/ {
          proxy_pass http://loadbalancer;
          proxy_buffering         on;
        }

        location /api/ {
          proxy_pass http://loadbalancer;
          proxy_buffering         on;
        }

        location /email/ {
          proxy_pass http://loadbalancer;
          proxy_buffering         on;
        }
}

I would define the locations for your backend services using a trailing slash like /api/ and /email/ for example. Reason is that without the slash nginx would match your user location for a incomming request to /userbob in the same it would do for user.

2nd the proxy_buffering can be removed IF your are not turning it off on server or http level as on is default.

https://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_buffering

Answered By – Timo Stark

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published