I am having trouble understanding the concept of static and dynamic sites within the context of a React app. I am reading about how you can deploy React apps to Netlify which is known for hosting static sites. But all the React apps I've made make requests to Node/Express backends and shows the data that gets returned from them. I'm pretty sure that would make my React apps dynamic. Does this mean that I wouldn't be able to deploy them to Netlify?
You would be able to host the frontend part on Netlify that makes request to a backend elsewhere. But you won't be able to host the backend on Netlify, unless you convert it into serverless functions.
let api = ""
if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) {
//production
API = "https://project-sprint.herokuapp.com";
} else {
//development
API = "http://localhost:3001";
}
/
/ after i concat endpoint complement with this base, then no problem when i deploy
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 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.
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.
I'm trying to figure out what are the best practices to deploy a React app that consumes an API on a different host in production.
Currently in DEV I have the following:
frontend - React app running on webpack server: http://localhost:3000/
backend - API (django-rest) running on: http://localhost:7000/
Right now I define the API url in package.json proxy attribute: "proxy": "http://localhost:7000/", and I make API calls using Axios to api/something/something/ etc.
Both apps are standalone with separate repos and I'd like to keep it that way (I don't want to merge both apps into a single codebase.)
My question:
What is the best way to configure React in production to consume the production URL?
Use process.env.NODE_ENV to find out the current environment and assign the proper url to your base url constant.
In development, you will get process.env.NODE_ENV as "development" and in production, you will get process.env.NODE_ENV as "production".
I have configured create-react-app to use https in my local development environment. I would now like to convert my React application to a progressive web app and I plan to use Lighthouse to check my status. I am running Lighthouse as a Chrome plugin, but I am having trouble with the part when it is checking if my HTTP requests are redirected to HTTPS. They are not.
I have been crawling through my node_modules and I have taken a look at webpack-dev-server that is bundled with create-react-app. I have tried to make some changes, but the best I have managed so far is that I have gotten "Too many redirects".
TL;DR: How can I configure create-react-app to redirect all requests from http to https on my local dev environment?
Here's the code from my create-react-app if you are having trouble with just the redirect part. I'm doing it manually since Heroku doesn't automatically handle it. But this actually needs to be handled on the server because it makes the app visibly load twice if it has to redirect to http. But for now, I'm redirecting in the constructor of my App component.
constructor(props, context) {
const url = window.location.origin
if (!url.includes('localhost') && !url.includes('https')) {
window.location = `https:${url.split(':'))[1]}`
}
}
For your purposes, you'd just need to take out the localhost part and make the new url a little differently (because of the port).
I'm using ramda here, but lodash also has a tail function you can use.
import { tail } from 'ramda
...
constructor(props, context) {
const url = window.location.origin
if (!url.includes('https')) {
window.location = `https:${tail(url.split(':')).join(':')}`
}
}
#Fmacs, for redirection of HTTP traffic to HTTPS, instead of using local dev-server, deploy your app on any environment like Heroku or Firebase. Firebase is very simple. I see that you also have other issues running the create-react-app that you created. I have explained how to do this in simple steps in a blog post with sample code in GitHub. Please refer to: http://softwaredevelopercentral.blogspot.com/2019/10/react-pwa-tutorial.html