Redirect from http to https on localhost with create-react-app to test with Lighthouse - reactjs

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

Related

How to connect a React frontend on Netlify to a Flask backend on PythonAnywhere

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

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.

How to deploy Next.js app without Node.js server?

I was hoping to deploy a Next.js app with Laravel API. I had developed React apps with CRA and in those I used the API server to serve the index.html of the CRA as the entry point of the app.
But in Next.js, after development I get to know that it needs a Node.js server to serve (which is my bad, didn't notice that). There is an option next export that builds a static representation of the Next.js app and it has an index.html. I am serving the index.html as the entry of the app by my Laravel API. It is serving the page, but just some of the static contents.
What I was hoping to know is it possible to host the aPI and the Next app from a single PHP shared hosting without any node server? If so, how? If not so, what could be the alternatives?
Actually the acepted answer is completly wrong, when you do yarn build and in your package.json is set like "build": "next build && next export", you will get an out folder which all the items in there are used to build without node.js server
Now since you are using laravel, and you use the out folder you will only load half of the page because the routes are not set properly. for that to work you need to edit your next.config.js edit it to
module.exports = {
distDir: '/resources/views',
assetPrefix: '/resources/views',
}
These will set the root directory to the root one in Laravel. now this will work for SPA (single page application) only for the dynamic routes you need to match with a view file for each one that you have in your out folder
For each route that you have you need to create a new "get" route in laravel
Route::get('/', function () {
return require resource_path('views/index.html');
});
Route::get('/contacts', function () {
return require resource_path('views/contacts.html');
});
Route::get('/post/{slug}', function () {
return require resource_path('views/post/[slug].html');
});
Notice that you can pass a wildcard for dynamic routes and they are all gonna work. once you do that and you deploy route out folder inside /resources/views in Laravel it's going to work
Apparently there is no alternative to nodejs server, which is not an option for me currently, so I unfortunately had to abandon next.js and create a CRA app and used as much from the next.js as I could.

Heroku: Django backend is not working, getting error GET http://localhost:8000/api/todos/ net::ERR_CONNECTION_REFUSED

I actually created a fullstack todo app with django as backend and react as frontend. The frontend is working perfectly fine, you can that here -> https://ym-todo-application.herokuapp.com. But somehow my application cannot connect to the django backend, also on inspecting on browser i saw this error -> GET http://localhost:8000/api/todos/ net::ERR_CONNECTION_REFUSED.
Containing lot of files and code so i pushed them on bitbucket to make it easier to debug. here's the link https://bitbucket.org/Yash-Marmat/todo-app-fullstack/src/master/.
Thanks in advance.
You need to change the REST API server address. The localhost:8000 is the server address used in the development.
What is more, I see in your code that each time you write the request you have hard-coded server URL. You don't need to do this. You can set the server address by setting baseURL:
import axios from "axios";
if (window.location.origin === "http://localhost:3000") {
axios.defaults.baseURL = "http://127.0.0.1:8000"; // development address
} else {
axios.defaults.baseURL = window.location.origin; // production address
}
Then in the request, you only write the endpoint address, example:
axios.put(`/api/todos/${item.id}/`, item)
Please see my article Docker-Compose for Django and React with Nginx reverse-proxy and Let's Encrypt certificate for more details about Django and React deployment.

ReactJS backend requests and proxy

I have a couple of questions regarding how ReactJS should work in development and production. My ReactJS application was built starting from creare-react-app boilerplate. I have a SpringBoot backend listening on port 8080. The first thing I noticed is that if I set a code like this to make requests the code hang:
async componentDidMount() {
...
const response = await fetch('http://localhost:8080/api/compliance');
I need to convert it into:
async componentDidMount() {
...
const response = await fetch('/api/compliance');
and then add the line:
"proxy": "http://localhost:8080",
and this works fine. The problem is that when I put this in a pre-production environment (or integration environment) where I have a URL like http://www.mywebsite.com I got:
Invalid Host Header
Looking on the web I noticed that probably this could be to:
1. proxy that checks. the HTTP Header host and verify it to avoid security attacks
2. webpack package
I would like to understand:
1. Is proxy really necessary to let ReactJS app talk with its backend?
2. If no, how I can solve the issue (currently solution on the web didn't solve my problem)?
Generally proxy is not meant for production. Your app should provide both app and api on same port, on one server. https://stackoverflow.com/a/46771744/8522881

Resources