ReactJS/Next.js: CRA Proxy Does Not Work With Next.js (Attempting To Route API Request To Express server) - reactjs

I'm currently upgrading a vanilla React app to use Next.js (version 7.0.0). The app was originally built with Create-React-App and utilizes the proxy built in to CRA's server.
In development my React app runs on port 3000 and I have an Express server running on port 5000. Prior to adding Next.js I'd been using a proxy object within the package.json file to route API requests to the server.
API request:
const res = await axios.get('/api/request')
Proxy object in package.json:
"proxy": {
"/api/*": {
"target": "http://localhost:5000"
}
}
This had been working great, but with Next.js I'm now getting an error:
GET http://localhost:3000/api/request 404 (Not Found)
^ This is supposed to be pointing to locahost:5000 (my server)
Does anyone know how I might be able to route API requests from a React/Next.js client to an Express server running on a different port?

OK, so I've figured this out. You can create a Node.js proxy for Express by using http-proxy-middleware
You can then configure the target option to proxy requests to the correct domain:
const proxy = require('http-proxy-middleware')
app.use('/api', proxy({ target: 'http://localhost:5000', changeOrigin: true }));

Related

How to configure a react capacitor app running on mobile by usb to make http request to sendbird as localhost instead of its IP address?

I have a React webapp that I have converted it to native app using Capacitor. For live reloading, I had to edit capacitor.config.json as follows:
const config: CapacitorConfig = {
//
webDir: 'build',
bundledWebRuntime: false,
server: {
url: 'http://192.XXX.XXX:3000',
cleartext: true
},
};
This works just fine until the app makes a request to sendbird for initialization. I get the error message: 'SendBirdCall needs https connection, except for 'localhost' or '127.0.0.1'. I tried to setup an express https server but failed. Later I created two channels using ngrok - one for the server and one for the app. The sendbird request was successful but the graphql websocket was failing as ngrok does not support websocket links, also tried a tcp link but it failed as well.
I have another app that I created using the Sendbird React Native Quickstart project and I did not need to do any configuration for that. What could be done in order to make sendbird request using localhost from mobile connected via usb while also being able to have a ws connection?
Try to change the url:
const config: CapacitorConfig = {
...
server: {
url: 'http://localhost:3000',
cleartext: true
},
};
And after connecting a physical device execute the following:
cd $ANDROID_HOME/platform-tools
./adb reverse tcp:3000 tcp:3000
Where $ANDROID_HOME is the Android SDK directory.

React App doesn't make proxy calls after deployed to azure

Simple setup:
React App created with create-react-app
ASP.NET Core web API - a couple of controllers (currently no security until I make it work)
Both the API and Application are deployed to Azure.
When I run the app locally with configured proxy (I contact the deployed API on Azure) it works correctly makes the calls.
If I try the API directly from my machine it works too (PostMan for example)
When I open the deployed React APP - The application loads correctly but the call to the API doesn't get proxy(ed). What I mean it's not returning 404, 403 - it returns status 200, but makes the call to the app itself instead of proxy the request to the API.
I've tried both using "proxy" configuration in package.json as well as using "http-proxy-middleware". Both cases work with locally running app, but not deployed. Here is the configuration of the proxy:
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'https://XXXXXX.azurewebsites.net',
changeOrigin: true,
})
);
};
I suppose it's something related to the configuration of the node server used when I deploy to azure, but I don't have a clue what.
I've used the following tutorial for deployment: https://websitebeaver.com/deploy-create-react-app-to-azure-app-services
But as seen from content there is no proxy part in it.
After long troubleshooting I realize the issue was due to wrong understanding of the proxy configuration.
So I was not realizing the proxy configuration is respected only in debug mode and totally ignored into prod build. And of course while debugging the issue I was not realizing the Azure Deployment pipe was doing production build. So the resolution was to detect the production/dev on application layer and inject correct URL.
Here I hit another issue - process.env.NODE_ENV, which I was using to distinguish between development and production was undefined into my index.tsx - it was available in App.tsx and all its children, but not in index.tsx where my dependency container was initialized.
What resolved my issue is package called dotenv. Then I've just imported it into index.tsx and the process.env was available.
import * as dotenv from 'dotenv';

Proxying api requests in production for React/Express app

I'm working on a MERN-stack project using separated repositories (backend & frontend), In development environment, I was using "proxy" to connect the server API with react, and it was working perfectly.
//package.json in react
{
...
"proxy": "http://localhost:8000/",
...
}
But when I switched to production environment and replaced the proxy value with the deployed link, "proxy" is no longer supported. I did a search about it and I figured out that it's only for development env, and I tried several solutions found there on the internet but with no luck!
By the way, I'm deploying the backend with Heroku, and the frontend with Netlify. Right now, both of them are deployed without any error, but there is no connection between the backend and frontend.
In production we can't use (proxy).. instead we can set a variable in the frontend for the backend URL, and vise versa.
Let's start with backend configurations:
app.use(cors({
origin: "frontend_URL",
credentials: true
}));
Now, let's see the frontend config:
set a variable anywhere you prefer:
export const API_URL = "URL";
in the file where you call your API:
import axios from "axios";
import { API_URL } from "./your/path";
axios.defaults.withCredentials = true;
axios.get(`${API_URL}/your/route`);
and now you are ready to deploy...

How to add react.js to spring mvc application

I have a Spring MVC application (jsp as a views) and i want to add react.js as a frontend. I have a couple of questions:
1. Where i should place my create-react-app folder or it doesn't matter.
2. Is there a way to run the application from maven (war) only. I mean that i know only one way to run application it is start backend from maven and start react.js from npm start. But this approach requires to use proxy or cors (or i'm wrong). I am using IntellijI IDEA and WebStorm.
project structure here
It doesn't matter
You are right that you should run it on different servers for spring and react.
You can proxy your api request to the backend to avoid CORS issue.
Copy this to your src/setupProxy.js in your create-react-app. More info here
const proxy = require("http-proxy-middleware");
module.exports = app => {
app.use(
proxy("/api", {
target: "http://jsonplaceholder.typicode.com",
pathRewrite: { "^/api": "" },
changeOrigin: true
})
);
};
Then you can proxy request to your backend using /api prefix. Example i can do something like fetch('/api/users') in my frontend react app

why proxy not working when used with webpack

I have a node.js Server listening on 3300. It is tested okay with postman.
I have a react app created using create-react-app listening on 3000 and package.json having the statement "proxy":"http://localhost:3300". This is also tested okay.
I have another react app on the same machine, which is using webpack and listening on 8080. The package.json also has the same proxy statement "proxy":"http://localhost:3300" . In this case, when I am calling the api /api/users, my console log says
api-auth.js:5 POST http://localhost:8080/auth/signin/ 404 (Not Found)
if I directly call the api as
fetch('http://localhost:3300/api/users')
it fails with CORS error.
just to be more clear, this failing react app is actually downloaded from http://mdbootstrap.com in which I add a login form to test if it works.
Can you please help me resolve this issue?
As per my understanding just by adding the proxy line in the package.json does the trick but somehow it does not work when webpack is used.... is there something I should do in webpack as well?
Unless I'm mistaken, { proxy } from package.json is not read by webpack, webpack-dev-middleware or webpack-dev-server. It would explain the 404 response you are receiving.
You should try configuring { devServer.proxy }. If you would prefer, you can even import package.json to get the server URL.
Here's a simple example with with a web server proxying requests to an API server listening on localhost:3000.
You don't need proxy for this, you can install npm package "cors".
https://www.npmjs.com/package/cors
And use it at you node.js server. Here is how i use it at my express.js server.
const express = require('express');
const cors = require('cors');
const app = express();
app.use(cors());

Resources