React JS routes do not work in production

Asked

Viewed 174 times

0

I made a small web system and deployed it in Heroku, it turns out that the routes work normally in development, but in production the routes are not rendered and I have the following error "Cannot GET [route name]" I have researched on several sites people with similar problems but still can not solve

my Index.js

import React from "react";
import ReactDOM from "react-dom";
import { BrowserRouter,Router, Route, Switch, Redirect, } from "react-router-dom";

// core components
import Admin from "layouts/Admin.js";
import Login from './Login/Login'

import "assets/css/material-dashboard-react.css?v=1.9.0";

//const hist = createBrowserHistory();
import {history} from './history'
import PrivateRoute from './PrivateRoute/PrivateRoute'
import { AuthProvider } from "./Provider/auth";

ReactDOM.render(
  <BrowserRouter>
    <Switch>
      <Route path="/login" component={Login}/>
      <Route path="/admin" component={Admin} />{/*rota home*/}
      <Redirect from="/" to="/Login" />
    </Switch>
  </BrowserRouter>,
  document.getElementById("root")
);

my package.json

{
  "name": "meu-site",
  "version": "1.9.0",
  "private": false,
  "main": "dist/index.js",
  "dependencies": {
    "@material-ui/core": "4.10.0",
    "@material-ui/icons": "4.9.1",
    "axios": "^0.21.1",
    "chartist": "0.10.1",
    "classnames": "2.2.6",
    "crypto-js": "^4.0.0",
    "express": "^4.17.1",
    "formik": "^2.2.6",
    "history": "4.10.1",
    "perfect-scrollbar": "1.5.0",
    "prop-types": "15.7.2",
    "react": "16.13.1",
    "react-chartist": "0.14.3",
    "react-dom": "16.13.1",
    "react-google-maps": "9.4.5",
    "react-redux": "^7.2.4",
    "react-router-dom": "5.2.0",
    "react-scripts": "3.4.1",
    "react-swipeable-views": "0.13.9",
    "redux": "^4.1.0"
  },
  "scripts": {
    "dev": "react-scripts start",
    "start": "react-scripts start",
    "build": "react-scripts build",
    "test": "react-scripts test --env=jsdom",
    "eject": "react-scripts eject",
    "install:clean": "rm -rf node_modules/ && rm -rf package-lock.json && npm install && npm start",
    "lint:check": "eslint . --ext=js,jsx;  exit 0",
    "lint:fix": "eslint . --ext=js,jsx --fix;  exit 0",
    "build-package": "npm run build-package-css && babel src --out-dir dist"
  },
  "optionalDependencies": {
    "@types/googlemaps": "3.39.6",
    "@types/markerclustererplus": "2.1.33",
    "ajv": "6.12.2",
    "typescript": "3.9.3"
  },
  "devDependencies": {
    "eslint-config-prettier": "6.11.0",
    "eslint-plugin-prettier": "3.1.3",
    "gulp": "4.0.2",
    "gulp-append-prepend": "1.0.8",
    "prettier": "2.0.5"
  },
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": []
  }
}

the deploy was made in Heroku and the failure also happens when trying to reload the page, the system opens the first page and according to that I click the buttons everything happens normally, but when I try to put the route name in the browser bar or try to reload the page it all happens.

Server:

const express = require('express')
const {resolve}= require('path')
const app = express()

app.use('/', express.static( resolve( __dirname, './build' ) ) ) 

app.listen(process.env.PORT || 3000,(err) => {
  if(err){
    return console.log(err)
  }
  console.log('Sistema no ar')
})
  • And the server code that’s serving the files is like?

  • I am using a "server.js" file and in package.json scripts at start goes "Node server.js" const express = require('express')&#xA;&#xA;const {resolve}= require('path')&#xA;&#xA;const app = express()&#xA;&#xA;app.use('/',&#xA; express.static(&#xA; resolve(&#xA; __dirname,&#xA; './build'&#xA; )&#xA; )&#xA;)&#xA;&#xA;&#xA;&#xA;app.listen(process.env.PORT || 3000,(err) => {&#xA; if(err){return console.log(err)}&#xA;&#xA; console.log('Sistema no ar')&#xA;})

  • the error message in Heroku is : at=info method=GET path="/admin" Dyno=web.1 connect=1ms service=3ms status=404 bytes=388 Protocol=https

  • 1

    Turns out you’re only serving the route / for your React application. Try app.use('/*', using /* instead of just /. This will make every request not met by any app.use previous is dealt with in this app.use('/*'

  • In doing so the errors changed from 404 to 301 or 304 I made the following change:const express = require('express')&#xA;&#xA;const {resolve}= require('path')&#xA;&#xA;const app = express()&#xA;&#xA;app.use('/*',&#xA; express.static(&#xA; resolve(&#xA; __dirname,&#xA; './build'&#xA; )&#xA; )&#xA;)&#xA;&#xA;app.listen(process.env.PORT || 3000,(err) => {&#xA; if(err){return console.log(err)}&#xA;&#xA; console.log('Sistema no ar')&#xA;}) 2021-05-13T18:15:16.723330+00:00 heroku[router]: at=info method=GET path="/static/js/2.69f5d869.chunk.js" status=301 bytes=520 protocol=https or status=304

2 answers

2


This is a fairly common problem no matter how simple it may seem to other people.

Basically the following things are happening with your project:

  1. Your React project works right on localhost because your webpack is probably set to redirect your requests for your index.html file regardless of which route is called.

  2. When Voce accesses your code from Heroku, requests fall on your webserver, and that route is not configured there so Voce shows us in your code.

When Voce uses the following line:

app.use('/', express.static( resolve( __dirname, './build' ) ) ) 

You say only to the request that calls the root from your website to show the contents of the build folder.

Now Voce needs to point ALL the other requests also for your build folder as well as in the line below:

app.use('/', express.static( resolve( __dirname, './build' ) ) ) 
app.use('*', express.static( resolve( __dirname, './build' ) ) ) // <- a magica esta aqui nesta linha

After that I believe your React routes should work on Heroku.

0

I had similar problem and could only solve by replacing the use of <BrowserRouter basename="/"> for <HashRouter basename="/">.

I had to adjust some href= also, including the # before the address url.

I rotated around to test, where:

  • Dev: rode with npm run dev straightforward

  • Prod: created the build with npm run-script build and rode with npm start

All routing effects (defects ... kkk) identified in the build production were the same identified in Heroku.

Create build and running in production saved me a lot of time as I didn’t have to wait for Heroku’s deployment time to test there.

I even found more complex solutions, but in my case, for a facul application, that was enough.

For those who want to see the code, follow the git link: https://github.com/grosaict/CDC-web-client

I hope I’ve helped

Browser other questions tagged

You are not signed in. Login or sign up in order to post.