Nginx Configuration for react production deployment - reactjs

In the React project, I used proxy in package.json to route the traffic of backend api calls to the backend server address.enter image description here. And in the project, I used axios to send requests such as: enter image description here I do not have to add any prefix in the request of axios api calls. However, what should I config in the Nginx after I running npm run build in the nginx.conf?
Here is the nginx config file, in which I have already defined a "/" proxyenter image description here What should I write to route the traffic of api calls in the production environment?

Related

How to change localhost API URL when deployed to Heroku?

I've deployed an server-side rendering React app (bundled without CRA):
it has an express server for server-side rendering (listens to port 3000 or process.env.PORT)
it has an express server for the API that serves the frontend (listens to port 8080 or process.env.PORT)
On localhost, the frontend makes a request to http://localhost:8080/api to get the data, which works perfectly.
From my understanding, when the app is in production, the base API URL should be the app's URL (eg. https://myapp.herokuapp.com) instead of http://localhost:8080, so I added this change in my code:
if the app is in dev, the frontend calls http://localhost:8080/api
if the app is in prod, the frontend calls https://myapp.herokuapp.com/api(I added https://myapp.herokuapp.com/as a config var in Heroku)
However, it doesn't work. My app is deployed successfully to Heroku and the SSR renders correctly, but the API call fails. (I also tried https://myapp.herokuapp.com/api:3000 which fails)
What should be the API URL to call a local server when the app is in production?
thanks a lot!
Well, as far as I know Heroku doesn't allow multiple ports and you will not be able to open 3000 for web and 8080 for api.
You can serve both on the same port and route /api to the api.
I have worked on a project that uses similar approach and below is the code:
app.use('/api', router); // every api route is in the router
app.use(express.static(staticDir));
It is also deployed to heroku.
full repo if you wish to take a look - https://github.com/berkeli/breteau-dashboard/blob/main/server/utils/createServer.js

locally host firebase backend with react frontend together, for debugging

I am building a react website with firebase functions backend.
I'm using firebase serve to locally host the node.js backend that I connect to my react code through express API endpoints, and I am using react-scripts start to test my react frontend app.
all my get requests in my react app use /some endpoint to communicate with my firebase localserver. But they are running on different ports. firebase serves it on localhost:5000 while react live server hosts it at localhost:3000.
I tried many things and couldn't get any useful way to make this work. I at last added my react project as a subfolder in my firebase project and made the hosting public path at firebase.json to my react build directory. It works now but I always have to run npm run build on my react app on every change, to make it compile my app into the build directory, which is painfully slow.
What is the proper way to do this? debug react app and firebase backend together.
I finally enabled cross-origin-requests on my server using cors module
Serverside code
const cors = require("cors");
app.get("/test", (req, res) => {
return cors()(req, res, async () => {
res.send("working...");
});
});
Serverside code
And then adding a simple config file in the react side, to switch between debugging and deployed testing really helped.
config.js
var domain = "";
// domain = "http://localhost:5000";
export {domain}
then whenever I use apis in react, I simply comment/uncomment the second line to switch between local and deployed testing.
Then whenever I use APIs, I append `domain` before every url in all references, eg fetch requests
import { domain } from "config.js";
fetch(domain + "/int-search", ...
Then it worked fine running both the firebase backend and the react application on localhost, using firebase serve and npm start for my react app.

Different IP addresses in production and test environment how to handle it automaticaly

I have an app with django backend and react frontend. When testing and coding i run my django app on local server 127.0.0.1:8000 and connecting all my react requests to those endpoints. However in production my django app run on a different ip address and everytime i changed my code and push my reactjs app to production server i have to change all the endpoints ip's.
What is the best way to handle it? (as a source control i use git i do not know if it makes any differences)
I set the axios.defaults.baseURL depending on the window.location.origin. Here is my setting:
if (window.location.origin === "http://localhost:3000") {
axios.defaults.baseURL = "http://127.0.0.1:8000";
} else {
axios.defaults.baseURL = window.location.origin;
}
The above config is from my article Docker-Compose for Django and React with Nginx reverse-proxy and Let's Encrypt certificate. I'm serving React with nginx, and have reverse-proxy to Django (also in nginx), that's why for production setting I'm just using the same address. In the case of development, I have REST API at 127.0.0.1:8000.
I prefer this dynamic setting than settin env files because I don't need to set any environment variables.

Can github pages send http requests to an external api?

I have recently developed an React app in which I made HTTP request to external API using Axios library. Then I used gh-pages to deploy it. But it doesn't even show up (it's a blank page). I know GitHub only hosts static pages. The React app is running perfectly fine on localhost.
When I host React App on Localhost using npm start and request data using HTTP GET request using Axios Library. I receive a JSON format data from the API. And I use this data to show on front end of the React App.
But when I host the react app on git hub pages and request for data using the same way. It does not send HTTP requests to the API. And hence webpage is static in nature
have you tried to change http:// to https://?
because browsers nowadays don't let http requests to happen

Build React app with express backend for domain http://example.com

I have a web application in React that I needed to implement a contact form. The application is created using create-react-app and the server folder added. For the form I used sendgrid mail. Does the server work on port 4567, how do the app build to work on the domain? It is a one-page application.
Thx, it is important.
When running in production, a React app is simple HTML, CSS, and JavaScript. These files are sent from your server to a client when requested in the same way that requests/responses are handled for any web page. There are a few steps that need to be done before your React app is ready for production
1: Create a Production Build
First you need to create a production build of your app. This process takes all of your separate .js or .jsx files and puts them together into a single minified file, and the same for .css. Then your index.html is updated to include a link to the CSS and script to the JS. This is done so that only three files will need to be sent rather than the 10s or 100s that exist in development.
If you used create-react-app to start your application, you can use the command:
npm run build
to do this. Otherwise, you need to have webpack installed, and then run:
node_modules/.bin/webpack --config webpack.prod.js --mode production
(which you might want to add as a script to package.json).
See React: Optimizing Performance for more.
2. Serve your Application
Now your server should have a route for your application and when it receives a request on that route, the server should respond by sending index.html from your client/build/ directory (where client/ is the directory of the React app).
Here is an example with Node/Express as the server (in app.js):
const path = require('path');
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname), 'client', 'build', 'index.html');
});
Note that this is just the way to send a static file using Node and can easily be done with any server.
Additional
You mentioned you want to submit forms with your application. If your routes for receiving POST requests match the routes that the forms are on (e.g. form is on /form and server listens for POST on /form) you can just use the default HTML form submission. However this is not a great way to do things when using React because then routing will be controlled by your server rather than by React. Instead you should use some sort of AJAX method to submit the form.
Since your server is now serving your React app (rather than React serving itself as in development), you can just make relative requests and those requests will be made to your server. For example the request (using the fetch API):
const models = await fetch('/api/models');
Will be made to your_host/api/models by default.
in the package.json add
"proxy": "http://localhost:4567"

Resources