Nginx routes and refresh cause 404 - reactjs

I've set up an Express and React website using nginx and Elastic Beanstalk. It works fine when navigating the website, but if I refresh on a route other than the home route, or try type in a specific route other than the home route it causes a 404.
I've found a lot of different solutions to do with changing the nginx.config, and think I'm one step away. This is my current nginx.config:
server {
listen 80;
server_name leaftherapyeb-env.eba-xyc63u32.eu-west-2.elasticbeanstalk.com www.leaftherapyeb-env.eba-xyc63u32.eu-west-2.elasticbeanstalk.com;
root /var/www/leaftherapyeb-env.eba-xyc63u32.eu-west-2.elasticbeanstalk.com;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
}
I've seen a lot of solutions suggesting to use root /usr/share/nginx/html;, however when I use this instead of the root above every page links to the nginx index.html. So I changed to try the root as the path to the domain, which I think I have wrong, but don't know how to work out the path, and currently causes 500 internal error on every route including the home route.
Any help would be massively appreciated, thanks.

I think your nginx config has the wrong syntax. In the below nginx.conf, the / location points to your index.html in the folder /var/www/html
server {
listen 80;
server_name leaftherapyeb-env.eba-xyc63u32.eu-west-2.elasticbeanstalk.com www.leaftherapyeb-env.eba-xyc63u32.eu-west-2.elasticbeanstalk.com;
location / {
root /var/www/html;
index index.html
try_files $uri $uri/ /index.html;
}
}
You need to manually copy all the content of the client/build folder to /var/www/html - or you can just create a symlink (which is IMO not the very best solution, but it should work)
ln -s client/build /var/www/html
If you want to work with a symlink, make sure to remove the folder before creating the symlink otherwise you get an error

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;
}

Nginx Subfolder admin react app under main react app

I have a situation where i have two apps developed in react.
User App
Admin App
I made a build of both apps and have placed the user app build in site directory, where as admin app build is inside site/admin directory
What i want is
when someone tries www.mydomain.com/admin, it should go to admin directory, where as if no admin is given in url then it should not look for admin instead user files should be served.
I am willing to change directory structure any possible way to make this urls work as expected.
I have given alot of time and tries but failed to achieve the result. I am missing something, possibly its related to try_files configuration but i am not sure yet.
Following is the Nginx file i have created so far for my needs.
If i write mydomain.org/admin, it works fine.
But when i write mydomain.org/admin/{someotherparam e-g dashboard}, it loads the main user react app instead of admin app. I guess it reads the index file of user in that case. How to make read the index file of admin if /admin/ is in the url on first.
I have not much knowledge on nginx configuration, thou i did tried google.
Only 1 task is remaining to do on my part is if i put admin directory and user directory separate.
But then i would have to do domain.org/user and domain.org/admin, which i do not want.
I want admin react to work only if there is admin in url in first place after url.
I am not sure how to get this to working.
server {
listen 80;
listen [::]:80;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name mydomain.org www.mydomain.org;
location / {
root /var/www/mydomain.org/html/frontend/site;
try_files $uri $uri/ /index.html;
}
location /admin(.*) {
root /var/www/mydomain.org/html/frontend/site/admin;
try_files $uri $uri/ /index.html;
}
}
I am using LEMP on ubuntu 18.
Could you try this config?
server {
listen 80;
listen [::]:80;
# Add index.php to the list if you are using PHP
index index.html index.htm index.nginx-debian.html;
server_name mydomain.org www.mydomain.org;
root /var/www/mydomain.org/html/frontend/site;
location / {
try_files $uri $uri/ /index.html;
}
location /admin {
try_files $uri $uri/ /admin/index.html;
}
}

How configure nginx for prerender React App?

I've got React app.
It works well on local machine (app + prerender-spa-plugin). I run it with command http-server into ./build package
However thing go wrong on server - it acts like if I launch it with serve-s command.
There is docker with nginx image on server.
I tried to reconfigure nginx the way that it uses different index.html for different URLs, but fail again
Do the problem with routing to directories that keeps static images?
How it could be resolved? or where I could find information about it?
You have to create virtual host on nginx server and point it to build folder of the app. Don't forget to run npm run build.
Simple nginx config
server {
listen 80;
listen [::]:80;
root /var/www/reactjsapp/build;
index index.html index.htm;
server_name reactjsapp.com;
location / {
try_files $uri /index.html;
}
location ~ /\.ht {
deny all;
}
}
I decided it.
My config
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
From official documentation:"It is possible to check directory’s existence by specifying a slash at the end of a name, e.g. “$uri/”."
https://i.stack.imgur.com/PusBE.png

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