I have been stuck on this for days now and I need the internet's help.
I have created a static HTML landing page project for my react application (These two projects are separate), and I wish to serve both of these using Nginx. My landing page project has its own directory structure and assets that look like so:
/homepage
--index.html
--contact.html
--about-us.html
/static
--css files, imgs, ect
My React application is a Create React Application and from what I understand, after you run npm build that gives you a folder called build
with all your project files properly bundled so that you can deploy it. Now I have two directories with all I need to serve the websites but I'm having a hard time doing so using Nginx.
I would like to have my landing page on / so www.example.com and www.example.com/contact , ect would lead to my landing page project and then www.example.com/app, with www.example.com/app/login, ect would lead to my react project.
My Nginx config looks like this:
# redirect to https
server {
listen 80;
server_name _;
return 301 https://$host$request_uri;
}
server{
listen 443 ssl;
ssl_certificate /etc/nginx/certs/localhost.pem;
ssl_certificate_key /etc/nginx/certs/localhost-key.pem;
proxy_cookie_path / "/; HTTPOnly; Secure";
location / {
root /usr/share/nginx/html/homepage/;
try_files $uri.html $uri $uri/ =404;
}
location /app/ {
alias /usr/share/nginx/html/app/;
try_files $uri $uri/ /index.html;
}
location /api/ {
proxy_pass http://backend:8080/;
}
}
I can properly see my react apps home page, but when I navigate to any other page such as https://localhost/app/test I get sent to a broken landing page's index.html (where all the links / styling are broken). So, the link https://localhost/app directs me to my react app's index.html but when I go to https://localhost/app/test is broken and it gives me the landing pages's broken index.html
How can I properly configure nginx to serve my react app's other routes alongside my landing page project?
EDIT:
For more information I added the fact that I am using React router for my react application and my index.tsx looks like so:
import React from "react";
import ReactDOM from "react-dom";
import "./index.css";
import * as serviceWorker from "./serviceWorker";
import { Route, BrowserRouter as Router, Switch } from "react-router-dom";
import Home from "./components/Home";
import Login from "./components/Login/Login";
import Dashboard from "./components/Dashboard";
import SignupPage from "./components/Signup/SignupPage";
import DashNavbar from "./components/DashNavbar";
import PersonCard from "./components/PersonCard/PersonCard";
import AnalyticsSmallCard from "./components/AnalyticsSmallCard";
import Test2 from "./components/Test2";
import Test from "./components/Test";
import PrivateRoute from "./components/PrivateRoute";
import NotesSideBar from "./components/NotesSideBar";
import NotesPage from "./components/NotesPage";
import WarningCard from "./components/WarningCard";
const App = (
<Router basename="/app">
<Switch>
<Route path="/" component={Home} />
<Route path="/login" component={Login} />
<Route path="/signup" component={SignupPage} />
<PrivateRoute exact path="/dashboard" component={Dashboard} />
<Route path="/test" component={WarningCard} />
</Switch>
</Router>
);
ReactDOM.render(App, document.getElementById("root"));
serviceWorker.unregister();
The way I currently have this working in a project is by adding a homepage
field in my package.json
file in the React app.
{
"name": "react-app-name",
...dependencies and such
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"homepage": "https://example.com/app",
"proxy": "https://example.com/api"
}
You need this in addition to the basename
property you already have in your Router
component. This should allow you to render those pages through the React Router. I assume the pathing in your NGINX file is correct if you can see the example.com/app
.
A web server, 'serves' files. When you visit example.com/app
, the webserver is just showing whatever is in /usr/share/nginx/html/app/index.html
, likewise if you visit example.com/app/login
, it will try to display what is in /usr/share/nginx/html/app/login/index.html
Without seeing or knowing how you built the react app, it's a little hard to know what the problem is. React, when you build will just create the single index.html along with a bunch of javascript inside the build directory.
This is why you can see it on your react homepage (www.example.com/app). But when you navigate to example.com/app/login you can't. Because there is an index.html for /app, but not for /app/login. Nginx is expecting an .html file under the /app/login directory.
Quick Solution: Most people will use React Router to create a multipage react app. This allows you to have routes within the react app.
Even though you only have the single index.html, you can create different 'pages' using react-router and it's all handled by the built javascript and you don't have to worry about creating a bunch of routes in Nginx. Just route to the react main app and react-router will handle the rest!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With