'ReactJS third party apis stops working on local after build

My ReactJS app has nothing but client-side and Third Part API integration. My app works totally fine along with thirdparty APIs if run on my local by

npm start

Making build through

npm run build

Then I'm serving up the build on my local by

serve -l 3000 -s build

Even tried running it on different port, example serve -s build -l 4000

and Build's app runs successfully on my local but APIs stops working, I start getting an error

You need to enable JavaScript to run this app.

This is my Package.json file

{
  "name": "****",
  "version": "0.1.0",
  "private": true,
  "dependencies": {
    "@material-ui/core": "^4.12.3",
    "@mui/material": "^5.0.6",
    "@testing-library/jest-dom": "^5.11.4",
    "@testing-library/react": "^11.1.0",
    "@testing-library/user-event": "^12.1.10",
    "antd": "^4.16.13",
    "axios": "^0.24.0",
    "bootstrap": "5.1.3",
    "http-proxy-middleware": "^2.0.4",
    "lodash": "^4.17.21",
    "material-ui-color": "^1.2.0",
    "material-ui-popup-state": "^2.0.0",
    "moment": "^2.29.1",
    "prop-types": "^15.7.2",
    "rc-color-picker": "^1.2.6",
    "react": "^17.0.2",
    "react-bootstrap": "^2.0.0",
    "react-bootstrap-range-slider": "^3.0.3",
    "react-bootstrap-timezone-picker": "^2.0.1",
    "react-dom": "^17.0.2",
    "react-icons": "^4.3.1",
    "react-redux": "^7.2.6",
    "react-router-dom": "^5.3.0",
    "react-scripts": "4.0.3",
    "react-switch": "^6.0.0",
    "react-time-picker": "^4.4.4",
    "react-toastify": "^8.1.0",
    "rgb-hex": "^4.0.0",
    "web-vitals": "^1.0.1"
  },
  "scripts": {
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test",
    "eject": "react-scripts eject",
    "PORT": "3000"
  },
  "eslintConfig": {
    "extends": [
      "react-app",
      "react-app/jest"
    ]
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

This is the fetch request for login which doesn't work in case of build on local or on live


      await fetch('api/v4/auth/login', {
        method: 'POST',
        headers: {
          Accept: 'application/json',
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          authenticationDetails: {
            applicationId: '****',
            email: email,
            password: password,
          },
          deviceDetails: {
            applicationVersion: '154',
            deviceId: '12345678',
            deviceModel: 'PIXEL',
            deviceType: 'PHONE',
            osType: 'ANDROID',
            osVersion: '9',
            timezone: {
              currentTimeInClientInMilliseconds: 0,
              offsetFromUTCInMilliseconds: 0,
              timeZoneId: 'UTC',
            },
          },
        }),
      })
        .then((response) => response.json())
        .then((result) => {
          if (result.errorCode === 401) {
            toast.error('Incorrect email or pasword!', {
              position: 'top-right',
              autoClose: 3000,
              hideProgressBar: true,
              closeOnClick: true,
              pauseOnHover: false,
              draggable: true,
              progress: undefined,
            });
          } else if (result.accessToken) {
            localStorage.setItem('token', result.accessToken);
            history.push('/dashboard');
            toast.success('User logged in successfully', {
              position: 'top-right',
              autoClose: 3000,
              hideProgressBar: true,
              closeOnClick: true,
              pauseOnHover: false,
              draggable: true,
              progress: undefined,
            });
          } else {
            toast.error('Error! While connecting to server', {
              position: 'top-right',
              autoClose: 3000,
              hideProgressBar: true,
              closeOnClick: true,
              pauseOnHover: false,
              draggable: true,
              progress: undefined,
            });
          }
        })
        .catch((error) =>
          toast.error('Error! While connecting to server', {
            position: 'top-right',
            autoClose: 3000,
            hideProgressBar: true,
            closeOnClick: true,
            pauseOnHover: false,
            draggable: true,
            progress: undefined,
          })
        );
    

There's a proxy setup as well

const { createProxyMiddleware } = require('http-proxy-middleware');

module.exports = function (app) {
  app.use(
    createProxyMiddleware('/api', {
      target: 'example.com', // API endpoint 1
      changeOrigin: true,
      pathRewrite: {
        '^/api': '',
      },
      headers: {
        Connection: 'keep-alive',
      },
    })
  );
  app.use(
    createProxyMiddleware('/control', {
      target: 'example2.com', // API endpoint 2
      changeOrigin: true,
      pathRewrite: {
        '^/control': '',
      },
      headers: {
        Connection: 'keep-alive',
      },
    })
  );
};

To Produce the error: Enter some gibrish username and password You'll see the result as follwing: The network tab: enter image description here enter image description here

Some people suggested I should have the same port when I run and I have made sure that both my app and build runs on port 3000

It's been a couple of days seems like a small issue that experts should be able to help me out here.

Any Questions you may have for me or anything which I may have missed to write please let me know.

I need to be able to run the build on localhost, if anyone wishes to see the project on live you may check https://dev.timeahead.co or https://624055f087ea1422bb7d7a5d--stellular-lolly-7512e5.netlify.app/ it throws the same error

Thanks



Solution 1:[1]

In server side you are trying render react app, when you make post request to server its just returning react app's index file

Proxy Middleware works automatically in Development server only If you want to proxy in production then you need to create separate express application

Serving with Serve package itself is not sufficient as serve is used to serve a static site and no server side logic(here proxy) will be evaluated

Sample will be

    const express = require('express');
    const { createProxyMiddleware } = require('http-proxy-middleware');
    
    const app = express();
    
    app.use(
    createProxyMiddleware('/api', {
      target: 'example.com', // API endpoint 1
      changeOrigin: true,
      pathRewrite: {
        '^/api': '',
      },
      headers: {
        Connection: 'keep-alive',
      },
    })
  );
  app.use(
    createProxyMiddleware('/control', {
      target: 'example2.com', // API endpoint 2
      changeOrigin: true,
      pathRewrite: {
        '^/control': '',
      },
      headers: {
        Connection: 'keep-alive',
      },
    })
  );
    app.listen(80);

now just run node filename.js along with serve -s build -l 4000

Since Server is running on different port you need to make necessary changes while serving through serve

If you want serve react through Express then add below code to above

// add middleware
app.use(express.static("public"));

If we are serving on same port no changes are required in react app

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1