Serve multiple React apps from the same server with Nginx - reactjs

I'm serving multiple react apps from the same server block in Nginx.I'm forwarding these routes from nginx to each react app's index.html, I've added a try_files to each location:
My nginx configuration :
server {
listen 80;
location /nest/ {
alias /Users/harikrishnan/turbolab/nest-ui/build;
try_files $uri /index.html;
}
location /nest/dataviewer/ {
alias /Users/harikrishnan/turbolab/dataviewer/dataviewer/build;
try_files $uri /index.html;
}
}
The problem is that when I browse to /nest/dataviewer it redirects to the /nest/. That's obviously not what is expected, since I want to have each location to forward to the index.html of the adequate project.

The regular expression (^nest/dataviewer) does not match the URI that begins with /nest/dataviewer. You are missing the leading /.
The location ~* { statement is missing any regular expression, I am surprised that nginx accepts it.
In this case, you should be using the prefix location, which is more efficient. See this document for details.
For example:
location /nest/dataviewer { ... }
location / { ... }

Related

Redirect root to /path/ for single page application and NGINX

What I'm trying to achieve is to have a project use the subdomain as part of the request path for react SPA.
e.g. qem.xxx.com -> xxx.com/qem for a SPA where the file path doesn't change with the request.
I've been messing about for a while with rewrites but haven't been able to achieve it. Most of the resources seem to deal with the opposite, or with non-SPAs where the file path matches.
Here's the latest conf:
server {
listen ${NGINX_PORT};
server_name ${NGINX_HOST}
charset utf-8;
client_max_body_size 20M;
# what file to server as index
root /src/build;
index index.html index.htm;
error_page 503 #maintenance;
location #maintenance {
root /src;
rewrite ^(.*)$ /deploy/maintenance.html break;
}
location / {
# First attempt to serve request as file, then
# as directory, then fall back to redirecting to index.html
if (-f /src/maintenance.txt) {
return 503;
}
try_files $uri $uri/ #qem /index.html;
}
location #qem {
rewrite ^ /qem/$request_uri?;
try_files $uri $uri/ /index.html;
}
}
EDIT: Further details as requested:
NGINX_HOST=qem.xxx.com
Only one SPA application, so only one index.html in folder root
Have static resources that $uri and $uri/ match, all site content is served by index.html
Trying to achieve access to qem.xxx.com to serve as if the user accessed xxx.com/qem/ (i.e. this subdomain serves that part of SPA)
Currently semi-works in that it serves a blank page (200s).
Even just a general steer in the correct direction would be great!
Cheers,
Carl

Why is my nginx routing my react app static files to my index.html

I want to host a demo app on a subroute of my domain. When I place the app in the root of the domain and use the following configuration, it works:
server {
server_name domain.com www.domain.com;
root /var/www/my-app/build;
index index.html index.htm;
location / {
try_files $uri /index.html =404;
}
}
But when i move it to a subroute using the following configuration, it correctly fetches the initial index.html but then routes the static file requests (for css, js, images...) to index.html as well.
server {
listen 80;
server_name domain.com www.domain.com;
location / {
}
location /demo-apps/my-app{
root /var/www/my-app/build;
try_files $uri /index.html =404;
}
}
And I don't understand why. Here's a screen capture of the request which succeeds but returns the index.html file instad of the js file:
And here's the folder structure on the server:
As I understand it, the request from the first screen capture should match the $uri condition in the second location block and return the corresponding js file but, clearly, I'm wrong. What do I need to change for this to work?
Before anyone asks, yes, I did restart nginx.
The path to the file is constructed by concatenating the value of root with the value of $uri. So a request for /demo-apps/my-app/css/foo.css will be looked for at /var/www/my-app/build/demo-apps/my-app/css/foo.css, which is the wrong place.
You can use alias instead (see this document), for example:
location /demo-apps/my-app {
alias /var/www/my-app/build;
try_files $uri /demo-apps/my-app/index.html;
}
However, using alias and try_files together can be problematic. See this long term issue.
Or use a regular expression location (see this dcoument) to extract the latter part of the URI, for example:
location ~ ^/demo-apps/my-app(/.*)?$ {
root /var/www/my-app/build;
try_files $1 /index.html =404;
}

Serving two different angular apps at one domain with wildcard in path

Say I have a Dog app written in AngularJS and I'm now adding a new Grooming sub-app written in Angular4
Right now I have nginx serving /api to a backend php server with the /api prefix rewritten off (so it doesn't know it's in a sub-path) and / served by the frontend AngularJS app. These are two distinct apps, each in their own server directory. This works fine right now.
Now we are adding a Grooming app that is written in ng4 and it should be served out as though it were a module of the main app, but from an entirely different server dir, e.g. /dogs/315/grooming
If I hard-code the location to match location /dogs/315/grooming it loads the ng4 index.html and attempts to serve the app, but if I use regex location ~ ^/dogs/([0-9]+)/grooming it skips over it and loads the / location.
The Grooming app expects a url like /dogs/315/* to set the context, then it uses additional url segments for its own functionality.
The try_files $uri $uri/ $uri.html /index.html in the location ~ ^/dogs/([0-9]+)/grooming block keeps sending the child app back to the parent.
Here's some sample snippets, the grooming portion has been rewritten and changed many ways, I'm only including it as an example:
# This works
location ^~ /api {
alias /home/forge/api.greatapp.com/current/public;
try_files $uri $uri/ #api;
}
# This works
location #api {
rewrite /api/(.*)$ /api/index.php?$query_string last;
}
# This doesn't work
location ~ ^/dog/([0-9]+)/grooming {
alias /home/forge/dog-grooming.greatapp.com/current/dist/;
try_files $uri $uri/ #grooming;
}
# Nor this
location #grooming {
rewrite ^/dog/([0-9]+)/grooming/(.*)$ /index.html break;
}
# This works
location / {
try_files $uri $uri/ $uri.html /index.html;
}
Completely stuck on the grooming portions; tried so many things I could be going down the entirely wrong road.
Posting answer as comments as I need formatting
Please try below
location ~ ^/dog/([0-9]+)/grooming/ {
alias /home/forge/dog-grooming.greatapp.com/current/dist/;
index index.html;
try_files $uri $uri/ =404;
}

Nginx rewrites for React app with 2 HTML pages

so I'm building a react site using browserHistory, my current Nginx setup serves index.html for all URLs, however I have split out my admin part of the site so I need any url under /admin to server admin.html but I can;t figure it out (not a server guy!).
This is my current config, any help would be greatly appreciated!
server {
listen 80;
server_name http://178.62.98.191/;
root /www/rawnet-one-web/dist;
index index.html index.htm;
rewrite ^/(.*)/$ $1 permanent;
location / {
auth_basic "Restricted";
auth_basic_user_file /www/.htpasswd;
try_files $uri /index.html;
}
}
Based on the examples in the location documentation, you should just have to define the /admin/ location and serve the /admin.html file for any location that matches it.
location /admin/ {
try_files $uri $uri/ /admin.html
}
If you want /admin to not have a trailing slash, you will need to hard code that location.
location = /admin {
try_files /admin.html
}

NGINX configuration: Angular SPA in root and Slim REST API in subfolder

I can't get it to work!
location ~ ^/(api) {
#api requests
include /etc/nginx/mime.types;
index index.php;
try_files $request_uri $request_uri/ /index.php?$query_string;
}
location / {
#angular app
try_files $uri /index.html?$query_string;
}
I can load the base api path, ie https://test.com/api and it returns the 404 json response as expected, since accessing the root of the api is illegal.
however, trying to run any route in the api, such as https://test.com/api/v1/authenticate and it ends up being passed to the front end application in the second location block!
Well, after some experimentation, i determined that having the api in a subdirectory was causing the problem. i moved the api's index.php from /api/index.php to to the root folder (/) and renamed it api.php
then by changing my slim app group from /v1 to /api/v1 the following nginx configuration now works correctly:
location ~ ^/api {
try_files $request_uri $request_uri/ /api.php?$query_string;
}
location / {
include /etc/nginx/mime.types;
try_files $uri /index.html?$query_string;
}

Resources