I have a very weird problem, if I run my app with client side rendering then all the routes work perfectly. However when I switch to SSR then it runs fine initially on http://localhost:8001 but when I load a new get request by hitting enter in the browser search bar to load a different route such as http://localhost:8001/covid then I get this error... This was generated with create-react-app
TypeError [ERR_INVALID_CALLBACK]: Callback must be a function. Received undefined at maybeCallback (fs.js:160:9) at Object.readFile (fs.js:311:14) at D:\Repo\WhiteTigerCreateReactApp\server/server.js:37:8 at Layer.handle [as handle_request] (D:\Repo\WhiteTigerCreateReactApp\node_modules\express\lib\router\layer.js:95:5) at next (D:\Repo\WhiteTigerCreateReactApp\node_modules\express\lib\router\route.js:137:13) at Route.dispatch (D:\Repo\WhiteTigerCreateReactApp\node_modules\express\lib\router\route.js:112:3) at Layer.handle [as handle_request] (D:\Repo\WhiteTigerCreateReactApp\node_modules\express\lib\router\layer.js:95:5) at D:\Repo\WhiteTigerCreateReactApp\node_modules\express\lib\router\index.js:281:22 at param (D:\Repo\WhiteTigerCreateReactApp\node_modules\express\lib\router\index.js:354:14) at param (D:\Repo\WhiteTigerCreateReactApp\node_modules\express\lib\router\index.js:365:14)
Here is my nodeJS file where I load the react app, I have commented out the line I use for client side render
import express from 'express';
import fs from 'fs';
import path from 'path';
import React from 'react';
import ReactDomServer from 'react-dom/server'
import App from '../src/components/App'
const PORT = 8001;
const app = express();
let indexPath = path.join(__dirname, '../build/index.html');
let buildPath = path.join(__dirname, '../build');
app.use(express.static(path.resolve(__dirname, '..', 'build')));
app.get('*', function (req, res) {
console.log("response",indexPath);
//SSR -------------------------
fs.readFile(indexPath), 'utf-8', (err, data) => {
if (err) {
console.log('error from server.js', err);
return res.status(500).send("Some error happened")
}
return res.send(data.replace(
"<div id='root'></div>",
`<div id="root">${ReactDomServer.renderToString(<App />)} </div>`));
}
//Client Render -----------------
//res.sendFile(indexPath);
});
app.listen(PORT, () => {
console.log(`App launced on ${PORT}`);
});
This is wrapped up with a seperate server file which is the one I am calling. This calls the code above.
require('ignore-styles')
require('@babel/register')({
ignore: [/(node_module)/],
presets: ['@babel/preset-env', '@babel/preset-react']
})
require('./server')
My react app has this entry point
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter as Router } from "react-router-dom";
/* ./ means search local file system*/
import './assets/css/styles.css';
import './assets/css/utility.css';
import './assets/css/animate.min.css';
import './assets/css/call-now.css';
import './assets/css/Contact-Form-Clean.css';
import './assets/css/betternav.min.css';
import App from './components/App';
//when importing from a module the file extension is omitted. */
import '../node_modules/font-awesome/css/font-awesome.min.css';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import '../node_modules/bootstrap/dist/js/bootstrap.min.js';
import reportWebVitals from './reportWebVitals';
ReactDOM.hydrate(
<React.StrictMode>
<Router>
<App />
</Router>
</React.StrictMode>,
document.getElementById('root')
);
reportWebVitals();
And my App component looks like this which has all the routes.. clearly something is not working or loading during SSR? :/
import { React, Component } from 'react';
import { Switch, Route } from 'react-router-dom'
import '../assets/css/header.css';
import '../assets/css/footer.css';
import Header from './header';
import Footer from './footer';
import Body from './body';
import ClientPage from './clientPage'
import CovidPage from './covidPage'
import Commercial from './commercialPage'
import CarpetFloorPage from './carpetFloor'
import IndustrialConstructionPage from './industrialConstructionPage';
import SafeContractorPage from './safeContractor';
import ContactPage from './contactPage';
import IndustrialCommercialPage from './industrialCommercialPage';
import Popper from 'popper.js';
import BetterNav from '../utility/betternav'
import PageNotFound from './notFoundPage';
class App extends Component {
componentDidMount()
{
BetterNav();
}
render() {
return (
<div>
<Header></Header>
<Switch>
<Route exact path='/' component={Body} />
<Route path='/clients' component={ClientPage} />
<Route path='/covid' component={CovidPage} />
<Route path='/commercial' component={Commercial} />
<Route path='/carpet-floor' component={CarpetFloorPage} />
<Route path='/industrial-construction' component={IndustrialConstructionPage} />
<Route path='/safe-contractor' component={SafeContractorPage} />
<Route path='/contact' component={ContactPage} />
<Route path='/industrial-commercial' component={IndustrialCommercialPage} />
<Route component={PageNotFound} />
</Switch>
<Footer></Footer>
</div>
);
}
}
export default App;
Since updating the code in server.js to
app.get('*', function (req, res) {
console.log("response",indexPath);
//SSR -------------------------
fs.readFile(indexPath, 'utf-8', (err, data) => {
if (err) {
console.log('error from server.js', err);
return res.status(500).send("Some error happened")
}
return res.send(data.replace(
"<div id='root'></div>",
`<div id="root">${ReactDomServer.renderToString(<App />)} </div>`));
})
//Client Render -----------------
//res.sendFile(indexPath);
});
The app loads at first with http://localhost:8001 no problem as usual. but when I go to http://localhost:8001/covid I get this error instead..
D:\Repo\WhiteTigerCreateReactApp\node_modules\react-dom\cjs\react-dom-server.node.development.js:3709 throw err; ^
TypeError: Cannot read property 'createElement' of undefined at App.render (D:\Repo\WhiteTigerCreateReactApp\src\components/App.js:30:7) at processChild (D:\Repo\WhiteTigerCreateReactApp\node_modules\react-dom\cjs\react-dom-server.node.development.js:3450:18) at resolve (D:\Repo\WhiteTigerCreateReactApp\node_modules\react-dom\cjs\react-dom-server.node.development.js:3270:5) at ReactDOMServerRenderer.render (D:\Repo\WhiteTigerCreateReactApp\node_modules\react-dom\cjs\react-dom-server.node.development.js:3753:22) at ReactDOMServerRenderer.read (D:\Repo\WhiteTigerCreateReactApp\node_modules\react-dom\cjs\react-dom-server.node.development.js:3690:29) at Object.renderToString (D:\Repo\WhiteTigerCreateReactApp\node_modules\react-dom\cjs\react-dom-server.node.development.js:4298:27) at D:\Repo\WhiteTigerCreateReactApp\server/server.js:27:46 at FSReqCallback.readFileAfterClose [as oncomplete] (internal/fs/read_file_context.js:63:3) npm ERR! code ELIFECYCLE npm ERR! errno 1 npm ERR! [email protected] ssr:
node server/index.js
npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the [email protected] ssr script.