I have a simple React app scaffolded to Heroku. Everything returns status code 200, and the favicon loads which tells me it should, technically, be rendering correctly. However, when I load the root page, where the React logo should appear, nothing shows up. There should also be some data rendering, and/or 'Loading...' should appeear if it hasn't loaded yet.
FYI, it is rendering locally just fine.
The deployment is located here: https://tduke-crud-frontend.herokuapp.com/
My server.js:
const express = require('express')
const PORT = process.env.PORT || 3001;
const server = express()
const api = require('./routes/api/api.js') // Router modules
const home = require('./routes/home.js')
const path = require('path')
server.use('/static', express.static(path.join(__dirname, 'public')))
server.use(express.static(path.join(__dirname, '../client/public')))
server.use(express.static(path.join(__dirname, '../client')))
server.use('/api', api) // Router files
server.use('/', home)
// GET routes
server.get('/', (req, res) => {
res.send('ExpressJS Server')
})
server.get('*', (req, res) => {
res.sendFile(path.resolve(__dirname, '../client/public', 'index.html'))
})
server.listen(PORT, () => {
console.log(`Server listening on PORT ${PORT}`)
})
module.exports = server
App.js:
import React from "react"
import logo from "./logo.svg"
import "./App.css"
function App() {
const [data, setData] = React.useState(null)
React.useEffect( () => {
try {
(async () => {
let d = await fetch('https://tdukedev-react-node.herokuapp.com/api', {
mode: 'cors'
})
.then((res) => res.json())
.then((data) => setData(data))
})()
} catch (err) {
console.error(err)
}
}, [])
return (
<div className="App">
<header className="App">
<img src={logo} alt="logo" className="App-logo"/>
<p>{!data ? 'Loading...' : data.users.title}</p>
</header>
</div>
)
}
export default App;
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="./favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="Web site created using create-react-app"
/>
<link rel="apple-touch-icon" href="./logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link rel="manifest" href="./manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>
server.js package.json:
{
"name": "server",
"version": "1.0.0",
"main": "server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node server/server.js",
"build": "cd client && npm install && npm run build ",
"client": "npm run start --prefix ./client"
},
"engines": {
"node": "16.x"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.3",
"nodemon": "^2.0.15"
},
"description": ""
}
Root package.json
{
"name": "server",
"version": "1.0.0",
"main": "./server/server.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "nodemon server/server.js",
"client": "npm run start --prefix ./client"
},
"engines": {
"node": "16.x"
},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"express": "^4.17.3",
"nodemon": "^2.0.15"
},
"description": ""
}
client package.json
{
"name": "client",
"version": "0.1.0",
"private": true,
"dependencies": {
"@testing-library/jest-dom": "^5.16.3",
"@testing-library/react": "^12.1.4",
"@testing-library/user-event": "^13.5.0",
"flowbite": "^1.4.1",
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react-scripts": "5.0.0",
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"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"
]
},
"devDependencies": {
"autoprefixer": "^10.4.4",
"postcss": "^8.4.12",
"tailwindcss": "^3.0.23"
}
}
My file structure:
-> tduke-react-node
-> client
-> node_modules
-> public
-> favicon.ico
-> index.html
-> logo192.png
-> logo512.png
-> manifest.json
-> robots.txt
-> src
-> App.css
-> App.js
-> index.css
-> index.js
-> logo.svg
-> reportWebVitals.js
-> setupTests.js
package.json
package-lock.json
postcss.config.js
README.md
tailwind.config.js
-> server
-> node_modules
-> routes
-> api
-> api.js
-> home.js
-> static
-> css
-> images
-> js
-> fake_db.json
package.json
package-lock.josn
sever.js
Most recent logs:
2022-03-26T11:53:59.273371 00:00 app[web.1]: Server listening on PORT 57371
2022-03-26T11:53:59.565960 00:00 heroku[web.1]: State changed from starting to up
2022-03-26T11:57:08.093185 00:00 app[web.1]: Successful 200 OK
2022-03-26T11:57:08.097678 00:00 heroku[router]: at=info method=GET path="/public/index.html" host=tduke-crud-frontend.herokuapp.
com request_id=6974d20d-8ba6-4790-92fd-820e0a0b5128 fwd="73.129.233.103" dyno=web.1 connect=0ms service=10ms status=200 bytes=197
7 protocol=https
2022-03-26T11:57:08.611874 00:00 app[web.1]: Successful 200 OK
2022-03-26T11:57:08.613081 00:00 heroku[router]: at=info method=GET path="/public/favicon.ico" host=tduke-crud-frontend.herokuapp
.com request_id=16f88e61-25ed-4ba8-b91a-86075c613bf6 fwd="73.129.233.103" dyno=web.1 connect=0ms service=2ms status=200 bytes=197
7 protocol=https
2022-03-26T11:57:08.691002 00:00 app[web.1]: Successful 200 OK
2022-03-26T11:57:08.692917 00:00 heroku[router]: at=info method=GET path="/public/manifest.json" host=tduke-crud-frontend.herokua
pp.com request_id=13ec9fa0-461c-47e2-b926-a3991dec43d9 fwd="73.129.233.103" dyno=web.1 connect=0ms service=3ms status=200 bytes=1
977 protocol=https
2022-03-26T11:57:12.552134 00:00 heroku[router]: at=info method=GET path="/" host=tduke-crud-frontend.herokuapp.com request_id=69
77dc96-f4b2-4dad-b86d-c8a5b314abbd fwd="73.129.233.103" dyno=web.1 connect=0ms service=2ms status=200 bytes=1977 protocol=https
2022-03-26T11:57:13.159708 00:00 heroku[router]: at=info method=GET path="/manifest.json" host=tduke-crud-frontend.herokuapp.com
request_id=55d3a107-3ae1-47de-b1d4-9d78f41bcd22 fwd="73.129.233.103" dyno=web.1 connect=0ms service=1ms status=200 bytes=788 prot
ocol=https
2022-03-26T11:57:13.424760 00:00 heroku[router]: at=info method=GET path="/logo192.png" host=tduke-crud-frontend.herokuapp.com re
quest_id=68160086-9573-4b0a-8e11-b41e4ccb2824 fwd="73.129.233.103" dyno=web.1 connect=0ms service=2ms status=200 bytes=5622 proto
col=https
2022-03-26T12:01:06.971883 00:00 app[web.1]: Successful 200 OK
2022-03-26T12:01:06.974524 00:00 heroku[router]: at=info method=GET path="/api" host=tduke-crud-frontend.herokuapp.com request_id
=0b62cd49-6352-4831-9a5b-f42aa9cd2e47 fwd="73.129.233.103" dyno=web.1 connect=0ms service=4ms status=304 bytes=183 protocol=https
CodePudding user response:
I once had a similar issue while trying to deploy my nodejs backend to heroku. The solution to my problem was that there is something called "Procfile" on the heroku servers, which has to be in the root directory of your repo. It's purpose is to basically just execute the command that you would use locally to start your app.
https://devcenter.heroku.com/articles/procfile
For my nodejs app, all I had to input into the procfile was web: node app.js
where app.js is like the "Main" file. For you it would be something along the lines of web: <whatever you use to start your app>
CodePudding user response:
When I visit your site, I am greeted with a page with the exact string you are sending here, ExpressJS Server
server.get('/', (req, res) => {
res.send('ExpressJS Server')
})
Where you are sending back the index.html page, I can't reach that route. If you return the page instead of a string here, I think you'll see your page. I can read the fake db json by visiting yourSite.com/api