I am using CRA to setup my react app.
I want to ask, how do I make a locally accessed react app do API call.
To explain my question, I can only do it by describing it.
So currently, my machine has 192.168.1.2 as its IP.
My backend server is running on 192.168.1.2:3000 (if i hit 192.168.1.2:3000/customers on browser I get the json response)
My frontend is running on 192.168.1.2:3001
If i open http://localhost:3001 or http://192.168.1.2:3001 from my laptop browser, all components render, it will render the Loading component and then not long after the list will render. (If i check my backend server, i can see that my server receives GET request)
However if I open http://192.168.1.2:3001 from my phone, all components render, but it is stuck at Loading component. When I check my backend server, it receives no request at all. So from what I can see is that by accessing my react app locally outside from the hosting machine, the app won't do any API call.
How do I fix this?
Things I have done:
Adding "proxy": "http://localhost:3000" and "proxy": "192.168.1.2:3000" to package.json (both doesn't work)
Changing "start" script to: "HOST=0.0.0.0 react-scripts start" and "react-scripts start --host=0.0.0.0" (both does not work)
My best guess is that you are fetching from localhost similar to this:
fetch("http://localhost:3000/customers")
The reason proxy isn't working in the config file would be because you need to remove "http://localhost:3000" from the fetch. Otherwise, it is still pinging localhost for the api, and not using the proxy setting. So it should look like this:
fetch("/customers")
Of course, without a reproducible example, it is hard to tell if that is exactly the problem you are having.
Related
TLDR: React app interfaces properly with Flask API on PythonAnywhere when hosted locally but not when a static build is hosted on Netlify. Perhaps the proxy information is missing from the build?
EDIT 1:
Here are the errors in the browser console:
I've created a Flask API that pulls machine learning models from Amazon S3 and returns predictions on data input from POST requests. I've put this API on PythonAnywhere.
I've also created a React frontend which allows me to input data, submit it, and then receive the prediction. When I host this app locally, it behaves appropriately (i.e. connecting to the Flask app on PythonAnywhere, loading the models properly, and returning the predictions).
I've tried deploying a static build of the React app on Netlify. It behaves as expected, except for anything that requires interacting with the Flask App. I have a button for testing that simply calls the Flask app in a GET request, and even this is throwing a 404 error.
I checked the error and server logs on PythonAnywhere and see nothing. The only thing I can thik of is that my proxy which lists the domain of the PythonAnywhere app in my package.json file is for some reason unincluded in the build, but I don't know why this would be the case.
Has anyone else run into a similar issue or know how I can check to see if the proxy information is included in the static build? Thanks in advance!
Thanks to #Glenn for the help.
Solution:
I realized (embarrassingly late) that the requests were not going to the right address, as can be seen in the browser console error above. I was using a proxy during development, so the netlify app was calling itself rather than the pythonanywhere API. I simply went into my react code and edited the paths to pythonanywhere. E.g.
onClick={ async () => {
const response = await fetch("/get", {...}}
became
onClick={ async () => {
const response = await fetch("https://username.pythonanywhere.com/get", {...}}
As #Glenn mentioned, there may have been a CORS issue as well, so in my flask application I utilized flask_cors. I can't say for sure that this was necessary given that I didn't test removing it after the fetch addresses had changed, but I suspect that it is necessary.
Hopefully this can help someone else
I would like to know if it is possible to alter all the api calls made from my react app to my backend server. I used to have the static files to sit around in my project root directory, so when I made an api call with axios like await axios.get('/api/my-endpoint') it all worked fine and my requests were translated to GET https://www.example-url.com/api/my-endpoint. But now I am migrating to AWS EC2 and decided to serve static files from AWS S3. So now since the api is in a remote server all my api calls are broken. I need to replace all api calls to https://www.another-example-url.com/api/.... I know I can set the new URL in an environment variable, but that would force me to manually alter all of the api URLs in my front-end codebase. I would not be very happy to do this, since there are almost a thousand of them.
I tried to set the axios baseURL like so:
import axios from "axios";
const instance = axios.create({
baseURL: "www.another-example-url.com"
});
export default instance;
but then all the requests were translated to GET https://www.example-url.com/www.another-example-url.com/api/my-endpoint
Is there a lazy way of doing this? Or do I have to manually alter them all?
You can easily set this using "proxy" field in package.json file of client side. Just add following line
...
"proxy": "https://www.another-example-url.com",
...
edit: I almost forgot that you were asking for production build. So react-amazing-proxy is an alternate to create-react-app proxy which can have feature to use proxy in production build.
Another lazy way, if you are familiar with docker, would be to Dockerize your development built.
I am using the next-auth.js library for authentication with Google in next.js. It is working fine in the localhost but I'm facing the issue in the Production environment. I went through the next-auth documentation and I found out it is a known issue with the environmental variables.
The error which I am facing is: [error][client_fetch_error] https://next-auth.js.org/errors#client_fetch_error. So I made changes in the code by adding an environmental variable which is NEXTAUTH_URL = "https://domainname/" as they mentioned in the documentation. Still, I am facing the same error also it is throwing a bad gateway request GET https://domaniname/api/auth/session 502 . Also, I ensured that the clientId, clientSecret are having the correct values and the Authorized redirect URIs: https://domainname/api/auth/callback/google
Could anyone help me out on how to rectify it?
You are facing this issue because you are trying to add dynamic API routing to a static website.
The documentation has a pretty good explanation of this.
Why This Warning Occurred
An exportPathMap path was matched to an API route. Statically exporting a Next.js application via next export disables API routes.
Now, it's likely you didn't set an exportPathMap directly (though you can do that in next.config.js). More likely, you are building your application with an extra export command in your build script in package.json - this is what is triggering the warning.
There is some more explanation on this in the Static HTML Export section:
API Routes are not supported by this method because they can't be prerendered to HTML.
... and in the API Routes section.
API Routes can't be used with next export
Okay, but how do I fix this?
The way to fix this is to make your application non-static (SSR or SSG). The easiest way to do this is to remove the export command, and add a start.
Package.json:
"scripts": {
"build": "next build",
"start": "next start"
}
You need to make sure that the start command is run - this might differ depending on your host.
its the first time i do electron app,
this app need to do API calls to lets say:
http:/<baseUrl>/someAPI
I need to change this "baseURL" on build somehow.
(can be anything...)
and cant use System.env when app is build.
i am using electron builder
I am thinking about creating a script and adding it to "package.json",
any thing more simple?
Thanks!
you can use proxy in package.json
Example
"proxy": "http://example.com"
so in each HTTP request will assign this proxy in the URL.
or you can use this package electron-proxy-agent
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"