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
Related
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.
here is my app link https://course-s.herokuapp.com/ and here is my Github repo https://github.com/shaikafroz016/Course-S . The app work perfectly in localhost whit express, MongoDB Atlas, and node server as a backend and react-redux as a frontend but when I am trying to run this on Heroku my says's failed to fetch whats the problem.
EDIT:
I have mentioned the base url as localhost:3000 in my client so should i have to add heroku app link to base url? can you please help me what to do. And also when i am trying the app with backend localhost (localhost:3000) it work just fine as i close my local server the heroku app says faild to fetch
This must be because of CORS (Access-Control-Allow-Origin), here's a workaround :
run npm install cors
and then add this to your app.js file :
var cors = require('cors')
app.use(cors())
Be sure to add this before all your requests definition (app.get, app.post, etc...)
Now CORS is enabled.
The Access-Control-Allow-Origin header determines which origins are allowed to access server resources over CORS.
Explanation : https://medium.com/#alexishevia/using-cors-in-express-cac7e29b005b
I have a React-Express app that pulls data from a MongoDB database on mLab.
On my server.js file, I have the api port set as such:
var port = process.env.PORT || 3001;
And it listens as such:
app.listen(port, function() {
console.log(`api running on port ${port}`);
});
Currently, in my React app, one of the components makes an AJAX call to the database on mLab using the url of "http://localhost:3001/api/data", which works fine and pulls the data I requested.
However, when I deploy the app to Heroku, I'm not sure how to configure the server.js and the url in the React app, so the React app is able to pull the data from the database.
I've conferred with mLab, and there are no issues, and I've conferred with Heroku, and this is beyond the scope of their support.
UPDATE: Is it that the process.env.PORT variable needs to be set or redirected?
Any ideas what I need to do?
Thanks!
If your express app is serving both your bundled react app and your api, you need to make sure that express knows that the /api endpoint needs to be NOT served to the react app.
Not sure what your server code looks like, but this has worked for me:
if (process.env.NODE_ENV === 'production') {
app.get(/^\/(?!api).*/, (req, res) => { // don't serve react app to api routes
res.sendFile(PATHTOREACTBUNDLE));
});
};
Basically, you want to tell express that, if in production mode (deploy on heroku), serve all endpoints, except the api endpoint (/^/(?!api) to your react bundle.
I have a React app deployed to production as a bundle.js and index.html pair, served up by IIS under a url like:
https://my-app.com
This talks to a .Net WebAPI backend, served up by IIS as a virtual application at
https://my-app.com/api
This allows the React app to make requests to the relative url /api/XXX and successfully hit the API.
My problem is when developing with these 2 projects running locally.
The API is run in Visual Studio 2015 in debug mode and IIS Express makes it available at http://localhost:56585/api/ (easily configurable).
While developing the React app I use JS development tools such as yarn, which provides a webserver hosting the app at http://localhost:3000.
The different webservers and different ports precludes the use of a relative url to contact the API when running locally. This means I have to hardcode the url my api hits, and change it before I build based on the target environment. Eg:
//const base_url = '/api/'; // production
const base_url = 'http://localhost:56585/api/'; // development
Is there any way to configure some kind of rewrite rule such that requests my client makes to /api/XXX get remapped to http://localhost:56585/XXX, without rewriting requests to the root url (eg http://localhost:3000/index.html)?
I am working on Angular 1 based web application.
I've deployed a web app with nginx , but couldn't deploy production server in my local env.
So, I want call API from the production server. For example,
I am using RestAngular to call API.
Restangular.all('api/user/profile').post(mUser)
This calls
localhost:8080/api/user/profile
because I've deployed a web app in localhost:8080.
I want to redirect requests which starts with "/API" to the production server, by config nginx properly.
So, in this case, it should call API server
http://devprod2api/api/user/profile
Other requests that don't start with "API" should go to:
http://localhost:8080/...
Is it something possible by config nginx properly? If possible, how can I do that?
I am not sure what you have tried, but this just needs a simple proxy_pass as far as I see. Add below to your nginx config and it should point all API to the other server. It assumes that a host entry is present for devprod2api
location /api/ {
proxy_pass http://devprod2api/api/;
}